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/smp_lock.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 const struct file_operations ip2mem_proc_fops;
142 static const struct file_operations ip2_proc_fops;
144 /********************/
145 /* Type Definitions */
146 /********************/
152 /* String constants to identify ourselves */
153 static const char pcName[] = "Computone IntelliPort Plus multiport driver";
154 static const char pcVersion[] = "1.2.14";
156 /* String constants for port names */
157 static const char pcDriver_name[] = "ip2";
158 static const char pcIpl[] = "ip2ipl";
160 /***********************/
161 /* Function Prototypes */
162 /***********************/
164 /* Global module entry functions */
166 /* Private (static) functions */
167 static int ip2_open(PTTY, struct file *);
168 static void ip2_close(PTTY, struct file *);
169 static int ip2_write(PTTY, const unsigned char *, int);
170 static int ip2_putchar(PTTY, unsigned char);
171 static void ip2_flush_chars(PTTY);
172 static int ip2_write_room(PTTY);
173 static int ip2_chars_in_buf(PTTY);
174 static void ip2_flush_buffer(PTTY);
175 static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
176 static void ip2_set_termios(PTTY, struct ktermios *);
177 static void ip2_set_line_discipline(PTTY);
178 static void ip2_throttle(PTTY);
179 static void ip2_unthrottle(PTTY);
180 static void ip2_stop(PTTY);
181 static void ip2_start(PTTY);
182 static void ip2_hangup(PTTY);
183 static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
184 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
185 unsigned int set, unsigned int clear);
187 static void set_irq(int, int);
188 static void ip2_interrupt_bh(struct work_struct *work);
189 static irqreturn_t ip2_interrupt(int irq, void *dev_id);
190 static void ip2_poll(unsigned long arg);
191 static inline void service_all_boards(void);
192 static void do_input(struct work_struct *);
193 static void do_status(struct work_struct *);
195 static void ip2_wait_until_sent(PTTY,int);
197 static void set_params (i2ChanStrPtr, struct ktermios *);
198 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
199 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
201 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
202 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
203 static long ip2_ipl_ioctl(struct file *, UINT, ULONG);
204 static int ip2_ipl_open(struct inode *, struct file *);
206 static int DumpTraceBuffer(char __user *, int);
207 static int DumpFifoBuffer( char __user *, int);
209 static void ip2_init_board(int, const struct firmware *);
210 static unsigned short find_eisa_board(int);
216 static struct tty_driver *ip2_tty_driver;
218 /* Here, then is a table of board pointers which the interrupt routine should
219 * scan through to determine who it must service.
221 static unsigned short i2nBoards; // Number of boards here
223 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
225 static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
226 //DevTableMem just used to save addresses for kfree
227 static void *DevTableMem[IP2_MAX_BOARDS];
229 /* This is the driver descriptor for the ip2ipl device, which is used to
230 * download the loadware to the boards.
232 static const struct file_operations ip2_ipl = {
233 .owner = THIS_MODULE,
234 .read = ip2_ipl_read,
235 .write = ip2_ipl_write,
236 .unlocked_ioctl = ip2_ipl_ioctl,
237 .open = ip2_ipl_open,
240 static unsigned long irq_counter;
241 static unsigned long bh_counter;
243 // Use immediate queue to service interrupts
245 //#define USE_IQ // PCI&2.2 needs work
247 /* The timer_list entry for our poll routine. If interrupt operation is not
248 * selected, the board is serviced periodically to see if anything needs doing.
250 #define POLL_TIMEOUT (jiffies + 1)
251 static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
253 #ifdef IP2DEBUG_TRACE
254 /* Trace (debug) buffer data */
255 #define TRACEMAX 1000
256 static unsigned long tracebuf[TRACEMAX];
257 static int tracestuff;
258 static int tracestrip;
259 static int tracewrap;
266 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
267 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \
268 tty->name,(pCh->flags), \
269 tty->count,/*GET_USE_COUNT(module)*/0,s)
278 #include "i2ellis.c" /* Extremely low-level interface services */
279 #include "i2cmd.c" /* Standard loadware command definitions */
280 #include "i2lib.c" /* High level interface services */
282 /* Configuration area for modprobe */
284 MODULE_AUTHOR("Doug McNash");
285 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
286 MODULE_LICENSE("GPL");
288 static int poll_only;
291 static int Eisa_slot;
294 static char rirqs[IP2_MAX_BOARDS];
295 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
297 /* Note: Add compiled in defaults to these arrays, not to the structure
298 in ip2.h any longer. That structure WILL get overridden
299 by these values, or command line values, or insmod values!!! =mhw=
301 static int io[IP2_MAX_BOARDS];
302 static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 };
304 MODULE_AUTHOR("Doug McNash");
305 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
306 module_param_array(irq, int, NULL, 0);
307 MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards");
308 module_param_array(io, int, NULL, 0);
309 MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards");
310 module_param(poll_only, bool, 0);
311 MODULE_PARM_DESC(poll_only, "Do not use card interrupts");
313 /* for sysfs class support */
314 static struct class *ip2_class;
316 /* Some functions to keep track of what irqs we have */
318 static int __init is_valid_irq(int irq)
322 while (*i != 0 && *i != irq)
328 static void __init mark_requested_irq(char irq)
330 rirqs[iindx++] = irq;
333 static int __exit clear_requested_irq(char irq)
336 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
337 if (rirqs[i] == irq) {
345 static int have_requested_irq(char irq)
347 /* array init to zeros so 0 irq will not be requested as a side
350 for (i = 0; i < IP2_MAX_BOARDS; ++i)
356 /******************************************************************************/
357 /* Function: cleanup_module() */
358 /* Parameters: None */
359 /* Returns: Nothing */
362 /* This is a required entry point for an installable module. It has to return */
363 /* the device and the driver to a passive state. It should not be necessary */
364 /* to reset the board fully, especially as the loadware is downloaded */
365 /* externally rather than in the driver. We just want to disable the board */
366 /* and clear the loadware to a reset state. To allow this there has to be a */
367 /* way to detect whether the board has the loadware running at init time to */
368 /* handle subsequent installations of the driver. All memory allocated by the */
369 /* driver should be returned since it may be unloaded from memory. */
370 /******************************************************************************/
371 static void __exit ip2_cleanup_module(void)
376 del_timer_sync(&PollTimer);
378 /* Reset the boards we have. */
379 for (i = 0; i < IP2_MAX_BOARDS; i++)
380 if (i2BoardPtrTable[i])
381 iiReset(i2BoardPtrTable[i]);
383 /* The following is done at most once, if any boards were installed. */
384 for (i = 0; i < IP2_MAX_BOARDS; i++) {
385 if (i2BoardPtrTable[i]) {
386 iiResetDelay(i2BoardPtrTable[i]);
387 /* free io addresses and Tibet */
388 release_region(ip2config.addr[i], 8);
389 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
390 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR,
393 /* Disable and remove interrupt handler. */
394 if (ip2config.irq[i] > 0 &&
395 have_requested_irq(ip2config.irq[i])) {
396 free_irq(ip2config.irq[i], (void *)&pcName);
397 clear_requested_irq(ip2config.irq[i]);
400 class_destroy(ip2_class);
401 err = tty_unregister_driver(ip2_tty_driver);
403 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n",
405 put_tty_driver(ip2_tty_driver);
406 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
407 remove_proc_entry("ip2mem", NULL);
410 for (i = 0; i < IP2_MAX_BOARDS; i++) {
413 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
414 pci_disable_device(ip2config.pci_dev[i]);
415 pci_dev_put(ip2config.pci_dev[i]);
416 ip2config.pci_dev[i] = NULL;
419 pB = i2BoardPtrTable[i];
422 i2BoardPtrTable[i] = NULL;
424 if (DevTableMem[i] != NULL) {
425 kfree(DevTableMem[i]);
426 DevTableMem[i] = NULL;
430 module_exit(ip2_cleanup_module);
432 static const struct tty_operations ip2_ops = {
436 .put_char = ip2_putchar,
437 .flush_chars = ip2_flush_chars,
438 .write_room = ip2_write_room,
439 .chars_in_buffer = ip2_chars_in_buf,
440 .flush_buffer = ip2_flush_buffer,
442 .throttle = ip2_throttle,
443 .unthrottle = ip2_unthrottle,
444 .set_termios = ip2_set_termios,
445 .set_ldisc = ip2_set_line_discipline,
448 .hangup = ip2_hangup,
449 .tiocmget = ip2_tiocmget,
450 .tiocmset = ip2_tiocmset,
451 .proc_fops = &ip2_proc_fops,
454 /******************************************************************************/
455 /* Function: ip2_loadmain() */
456 /* Parameters: irq, io from command line of insmod et. al. */
457 /* pointer to fip firmware and firmware size for boards */
458 /* Returns: Success (0) */
461 /* This was the required entry point for all drivers (now in ip2.c) */
462 /* It performs all */
463 /* initialisation of the devices and driver structures, and registers itself */
464 /* with the relevant kernel modules. */
465 /******************************************************************************/
466 /* IRQF_DISABLED - if set blocks all interrupts else only this line */
467 /* IRQF_SHARED - for shared irq PCI or maybe EISA only */
468 /* SA_RANDOM - can be source for cert. random number generators */
469 #define IP2_SA_FLAGS 0
472 static const struct firmware *ip2_request_firmware(void)
474 struct platform_device *pdev;
475 const struct firmware *fw;
477 pdev = platform_device_register_simple("ip2", 0, NULL, 0);
479 printk(KERN_ERR "Failed to register platform device for ip2\n");
482 if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) {
483 printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n");
486 platform_device_unregister(pdev);
491 /******************************************************************************
493 * str: kernel command line string
495 * Can't autoprobe the boards so user must specify configuration on
496 * kernel command line. Sane people build it modular but the others
499 * Alternating pairs of io,irq for up to 4 boards.
500 * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
505 * else => ISA I/O address
507 * irq=0 or invalid for ISA will revert to polling mode
509 * Any value = -1, do not overwrite compiled in value.
511 ******************************************************************************/
512 static int __init ip2_setup(char *str)
514 int j, ints[10]; /* 4 boards, 2 parameters + 2 */
517 str = get_options(str, ARRAY_SIZE(ints), ints);
519 for (i = 0, j = 1; i < 4; i++) {
533 __setup("ip2=", ip2_setup);
536 static int __init ip2_loadmain(void)
540 i2eBordStrPtr pB = NULL;
542 struct pci_dev *pdev = NULL;
543 const struct firmware *fw = NULL;
546 /* Hard lock the interrupts to zero */
547 irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0;
550 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0);
552 /* process command line arguments to modprobe or
553 insmod i.e. iop & irqp */
554 /* irqp and iop should ALWAYS be specified now... But we check
555 them individually just to be sure, anyways... */
556 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
557 ip2config.addr[i] = io[i];
559 ip2config.irq[i] = irq[i];
561 ip2config.irq[i] = 0;
562 /* This is a little bit of a hack. If poll_only=1 on command
563 line back in ip2.c OR all IRQs on all specified boards are
564 explicitly set to 0, then drop to poll only mode and override
565 PCI or EISA interrupts. This superceeds the old hack of
566 triggering if all interrupts were zero (like da default).
567 Still a hack but less prone to random acts of terrorism.
569 What we really should do, now that the IRQ default is set
570 to -1, is to use 0 as a hard coded, do not probe.
576 poll_only = !poll_only;
578 /* Announce our presence */
579 printk(KERN_INFO "%s version %s\n", pcName, pcVersion);
581 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
585 /* Initialise all the boards we can find (up to the maximum). */
586 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
587 switch (ip2config.addr[i]) {
588 case 0: /* skip this slot even if card is present */
591 /* ISA address must be specified */
592 if (ip2config.addr[i] < 0x100 ||
593 ip2config.addr[i] > 0x3f8) {
594 printk(KERN_ERR "IP2: Bad ISA board %d "
597 ip2config.addr[i] = 0;
600 ip2config.type[i] = ISA;
602 /* Check for valid irq argument, set for polling if
604 if (ip2config.irq[i] &&
605 !is_valid_irq(ip2config.irq[i])) {
606 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",
608 /* 0 is polling and is valid in that sense */
609 ip2config.irq[i] = 0;
618 pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
619 PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev);
621 ip2config.addr[i] = 0;
622 printk(KERN_ERR "IP2: PCI board %d not "
627 if (pci_enable_device(pdev)) {
628 dev_err(&pdev->dev, "can't enable device\n");
631 ip2config.type[i] = PCI;
632 ip2config.pci_dev[i] = pci_dev_get(pdev);
633 status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1,
636 ip2config.addr[i] = (USHORT)(addr & 0xfffe);
638 dev_err(&pdev->dev, "I/O address error\n");
640 ip2config.irq[i] = pdev->irq;
643 printk(KERN_ERR "IP2: PCI card specified but PCI "
644 "support not enabled.\n");
645 printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI "
647 #endif /* CONFIG_PCI */
650 ip2config.addr[i] = find_eisa_board(Eisa_slot + 1);
651 if (ip2config.addr[i] != 0) {
652 /* Eisa_irq set as side effect, boo */
653 ip2config.type[i] = EISA;
655 ip2config.irq[i] = Eisa_irq;
661 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
662 if (ip2config.addr[i]) {
663 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
665 i2BoardPtrTable[i] = pB;
666 iiSetAddress(pB, ip2config.addr[i],
670 printk(KERN_ERR "IP2: board memory allocation "
674 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
675 pB = i2BoardPtrTable[i];
681 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
682 /* We don't want to request the firmware unless we have at
684 if (i2BoardPtrTable[i] != NULL) {
686 fw = ip2_request_firmware();
689 ip2_init_board(i, fw);
693 release_firmware(fw);
695 ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0);
697 ip2_tty_driver->owner = THIS_MODULE;
698 ip2_tty_driver->name = "ttyF";
699 ip2_tty_driver->driver_name = pcDriver_name;
700 ip2_tty_driver->major = IP2_TTY_MAJOR;
701 ip2_tty_driver->minor_start = 0;
702 ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
703 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
704 ip2_tty_driver->init_termios = tty_std_termios;
705 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
706 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW |
707 TTY_DRIVER_DYNAMIC_DEV;
708 tty_set_operations(ip2_tty_driver, &ip2_ops);
710 ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0);
712 err = tty_register_driver(ip2_tty_driver);
714 printk(KERN_ERR "IP2: failed to register tty driver\n");
715 put_tty_driver(ip2_tty_driver);
716 return err; /* leaking resources */
719 err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl);
721 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n",
724 /* create the sysfs class */
725 ip2_class = class_create(THIS_MODULE, "ip2");
726 if (IS_ERR(ip2_class)) {
727 err = PTR_ERR(ip2_class);
731 /* Register the read_procmem thing */
732 if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) {
733 printk(KERN_ERR "IP2: failed to register read_procmem\n");
734 return -EIO; /* leaking resources */
737 ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0);
738 /* Register the interrupt handler or poll handler, depending upon the
739 * specified interrupt.
742 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
743 if (ip2config.addr[i] == 0)
746 pB = i2BoardPtrTable[i];
748 device_create(ip2_class, NULL,
749 MKDEV(IP2_IPL_MAJOR, 4 * i),
751 device_create(ip2_class, NULL,
752 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
755 for (box = 0; box < ABS_MAX_BOXES; box++)
756 for (j = 0; j < ABS_BIGGEST_BOX; j++)
757 if (pB->i2eChannelMap[box] & (1 << j))
760 j + ABS_BIGGEST_BOX *
761 (box+i*ABS_MAX_BOXES),
766 /* Poll only forces driver to only use polling and
767 to ignore the probed PCI or EISA interrupts. */
768 ip2config.irq[i] = CIR_POLL;
770 if (ip2config.irq[i] == CIR_POLL) {
772 if (!timer_pending(&PollTimer)) {
773 mod_timer(&PollTimer, POLL_TIMEOUT);
774 printk(KERN_INFO "IP2: polling\n");
777 if (have_requested_irq(ip2config.irq[i]))
779 rc = request_irq(ip2config.irq[i], ip2_interrupt,
781 (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
782 pcName, i2BoardPtrTable[i]);
784 printk(KERN_ERR "IP2: request_irq failed: "
786 ip2config.irq[i] = CIR_POLL;
787 printk(KERN_INFO "IP2: Polling %ld/sec.\n",
788 (POLL_TIMEOUT - jiffies));
791 mark_requested_irq(ip2config.irq[i]);
792 /* Initialise the interrupt handler bottom half
797 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
798 if (i2BoardPtrTable[i]) {
799 /* set and enable board interrupt */
800 set_irq(i, ip2config.irq[i]);
804 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0);
809 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
810 /* unregister and put tty here */
813 module_init(ip2_loadmain);
815 /******************************************************************************/
816 /* Function: ip2_init_board() */
817 /* Parameters: Index of board in configuration structure */
818 /* Returns: Success (0) */
821 /* This function initializes the specified board. The loadware is copied to */
822 /* the board, the channel structures are initialized, and the board details */
823 /* are reported on the console. */
824 /******************************************************************************/
826 ip2_init_board(int boardnum, const struct firmware *fw)
829 int nports = 0, nboxes = 0;
831 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
833 if ( !iiInitialize ( pB ) ) {
834 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
835 pB->i2eBase, pB->i2eError );
838 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
839 ip2config.addr[boardnum], ip2config.irq[boardnum] );
841 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
842 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
846 if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size )
848 printk ( KERN_ERR "IP2: failed to download loadware\n" );
849 goto err_release_region;
851 printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
852 pB->i2ePom.e.porVersion,
853 pB->i2ePom.e.porRevision,
854 pB->i2ePom.e.porSubRev, pB->i2eLVersion,
855 pB->i2eLRevision, pB->i2eLSub );
858 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
861 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
862 pB->i2ePom.e.porID );
864 goto err_release_region;
867 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
868 printk ( KERN_INFO "IP2: ISA-4\n" );
872 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
873 printk ( KERN_INFO "IP2: ISA-8 std\n" );
877 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
878 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
882 case POR_ID_FIIEX: /* IntelliPort IIEX */
884 int portnum = IP2_PORTS_PER_BOARD * boardnum;
887 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
888 if ( pB->i2eChannelMap[box] != 0 ) {
891 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
892 if ( pB->i2eChannelMap[box] & 1<< i ) {
897 DevTableMem[boardnum] = pCh =
898 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
900 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
901 goto err_release_region;
903 if ( !i2InitChannels( pB, nports, pCh ) ) {
904 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
906 goto err_release_region;
908 pB->i2eChannelPtr = &DevTable[portnum];
909 pB->i2eChannelCnt = ABS_MOST_PORTS;
911 for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
912 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
913 if ( pB->i2eChannelMap[box] & (1 << i) ) {
914 DevTable[portnum + i] = pCh;
915 pCh->port_index = portnum + i;
920 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
921 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
925 DevTableMem[boardnum] = pCh =
926 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
928 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
929 goto err_release_region;
931 pB->i2eChannelPtr = pCh;
932 pB->i2eChannelCnt = nports;
933 if ( !i2InitChannels( pB, nports, pCh ) ) {
934 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
936 goto err_release_region;
938 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
940 for( i = 0; i < pB->i2eChannelCnt; ++i ) {
941 DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
942 pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
946 INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh);
950 release_region(ip2config.addr[boardnum], 8);
953 i2BoardPtrTable[boardnum] = NULL;
957 /******************************************************************************/
958 /* Function: find_eisa_board ( int start_slot ) */
959 /* Parameters: First slot to check */
960 /* Returns: Address of EISA IntelliPort II controller */
963 /* This function searches for an EISA IntelliPort controller, starting */
964 /* from the specified slot number. If the motherboard is not identified as an */
965 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
966 /* it returns the base address of the controller. */
967 /******************************************************************************/
968 static unsigned short
969 find_eisa_board( int start_slot )
972 unsigned int idm = 0;
973 unsigned int idp = 0;
974 unsigned int base = 0;
981 * First a check for an EISA motherboard, which we do by comparing the
982 * EISA ID registers for the system board and the first couple of slots.
983 * No slot ID should match the system board ID, but on an ISA or PCI
984 * machine the odds are that an empty bus will return similar values for
988 value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
989 for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
990 j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
996 * OK, so we are inclined to believe that this is an EISA machine. Find
997 * an IntelliPort controller.
999 for( i = start_slot; i < 16; i++ ) {
1001 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
1002 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
1004 if ( idm == 0x0e8e ) {
1005 if ( idp == 0x0281 || idp == 0x0218 ) {
1007 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1008 ismine = 3; /* Can do edge-trigger */
1019 /* It's some sort of EISA card, but at what address is it configured? */
1021 setup_address = base + 0xc88;
1022 value = inb(base + 0xc86);
1023 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1025 if ( (ismine & 2) && !(value & 0x10) ) {
1026 ismine = 1; /* Could be edging, but not */
1029 if ( Eisa_irq == 0 ) {
1030 Eisa_irq = setup_irq;
1031 } else if ( Eisa_irq != setup_irq ) {
1032 printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
1035 #ifdef IP2DEBUG_INIT
1036 printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1037 base >> 12, idm, idp, setup_address);
1039 printk(KERN_DEBUG ", Interrupt %d %s\n",
1040 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1042 printk(KERN_DEBUG ", (polled)\n");
1045 return setup_address;
1048 /******************************************************************************/
1049 /* Function: set_irq() */
1050 /* Parameters: index to board in board table */
1052 /* Returns: Success (0) */
1055 /******************************************************************************/
1057 set_irq( int boardnum, int boardIrq )
1059 unsigned char tempCommand[16];
1060 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1061 unsigned long flags;
1064 * Notify the boards they may generate interrupts. This is done by
1065 * sending an in-line command to channel 0 on each board. This is why
1066 * the channels have to be defined already. For each board, if the
1067 * interrupt has never been defined, we must do so NOW, directly, since
1068 * board will not send flow control or even give an interrupt until this
1069 * is done. If polling we must send 0 as the interrupt parameter.
1072 // We will get an interrupt here at the end of this function
1074 iiDisableMailIrq(pB);
1076 /* We build up the entire packet header. */
1077 CHANNEL_OF(tempCommand) = 0;
1078 PTYPE_OF(tempCommand) = PTYPE_INLINE;
1079 CMD_COUNT_OF(tempCommand) = 2;
1080 (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
1081 (CMD_OF(tempCommand))[1] = boardIrq;
1083 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1084 * board will respond almost immediately after SendMail hit.
1086 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1087 iiWriteBuf(pB, tempCommand, 4);
1088 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1089 pB->i2eUsingIrq = boardIrq;
1090 pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1092 /* Need to update number of boards before you enable mailbox int */
1095 CHANNEL_OF(tempCommand) = 0;
1096 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1097 CMD_COUNT_OF(tempCommand) = 6;
1098 (CMD_OF(tempCommand))[0] = 88; // SILO
1099 (CMD_OF(tempCommand))[1] = 64; // chars
1100 (CMD_OF(tempCommand))[2] = 32; // ms
1102 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1103 (CMD_OF(tempCommand))[4] = 64; // chars
1105 (CMD_OF(tempCommand))[5] = 87; // HW_TEST
1106 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1107 iiWriteBuf(pB, tempCommand, 8);
1108 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1110 CHANNEL_OF(tempCommand) = 0;
1111 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1112 CMD_COUNT_OF(tempCommand) = 1;
1113 (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */
1114 iiWriteBuf(pB, tempCommand, 3);
1117 // enable heartbeat for test porpoises
1118 CHANNEL_OF(tempCommand) = 0;
1119 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1120 CMD_COUNT_OF(tempCommand) = 2;
1121 (CMD_OF(tempCommand))[0] = 44; /* get ping */
1122 (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
1123 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1124 iiWriteBuf(pB, tempCommand, 4);
1125 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1128 iiEnableMailIrq(pB);
1129 iiSendPendingMail(pB);
1132 /******************************************************************************/
1133 /* Interrupt Handler Section */
1134 /******************************************************************************/
1137 service_all_boards(void)
1142 /* Service every board on the list */
1143 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1144 pB = i2BoardPtrTable[i];
1146 i2ServiceBoard( pB );
1152 /******************************************************************************/
1153 /* Function: ip2_interrupt_bh(work) */
1154 /* Parameters: work - pointer to the board structure */
1155 /* Returns: Nothing */
1158 /* Service the board in a bottom half interrupt handler and then */
1159 /* reenable the board's interrupts if it has an IRQ number */
1161 /******************************************************************************/
1163 ip2_interrupt_bh(struct work_struct *work)
1165 i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt);
1166 // pB better well be set or we have a problem! We can only get
1167 // here from the IMMEDIATE queue. Here, we process the boards.
1168 // Checking pB doesn't cost much and it saves us from the sanity checkers.
1173 i2ServiceBoard( pB );
1174 if( pB->i2eUsingIrq ) {
1175 // Re-enable his interrupts
1176 iiEnableMailIrq(pB);
1182 /******************************************************************************/
1183 /* Function: ip2_interrupt(int irq, void *dev_id) */
1184 /* Parameters: irq - interrupt number */
1185 /* pointer to optional device ID structure */
1186 /* Returns: Nothing */
1190 /* Our task here is simply to identify each board which needs servicing. */
1191 /* If we are queuing then, queue it to be serviced, and disable its irq */
1192 /* mask otherwise process the board directly. */
1194 /* We could queue by IRQ but that just complicates things on both ends */
1195 /* with very little gain in performance (how many instructions does */
1196 /* it take to iterate on the immediate queue). */
1199 /******************************************************************************/
1201 ip2_irq_work(i2eBordStrPtr pB)
1204 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1205 // Disable his interrupt (will be enabled when serviced)
1206 // This is mostly to protect from reentrancy.
1207 iiDisableMailIrq(pB);
1209 // Park the board on the immediate queue for processing.
1210 schedule_work(&pB->tqueue_interrupt);
1212 // Make sure the immediate queue is flagged to fire.
1216 // We are using immediate servicing here. This sucks and can
1217 // cause all sorts of havoc with ppp and others. The failsafe
1218 // check on iiSendPendingMail could also throw a hairball.
1220 i2ServiceBoard( pB );
1222 #endif /* USE_IQI */
1226 ip2_polled_interrupt(void)
1231 ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0);
1233 /* Service just the boards on the list using this irq */
1234 for( i = 0; i < i2nBoards; ++i ) {
1235 pB = i2BoardPtrTable[i];
1237 // Only process those boards which match our IRQ.
1238 // IRQ = 0 for polled boards, we won't poll "IRQ" boards
1240 if (pB && pB->i2eUsingIrq == 0)
1246 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1250 ip2_interrupt(int irq, void *dev_id)
1252 i2eBordStrPtr pB = dev_id;
1254 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq );
1260 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1264 /******************************************************************************/
1265 /* Function: ip2_poll(unsigned long arg) */
1267 /* Returns: Nothing */
1270 /* This function calls the library routine i2ServiceBoard for each board in */
1271 /* the board table. This is used instead of the interrupt routine when polled */
1272 /* mode is specified. */
1273 /******************************************************************************/
1275 ip2_poll(unsigned long arg)
1277 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1279 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1280 // It will NOT poll boards handled by hard interrupts.
1281 // The issue of queued BH interrupts is handled in ip2_interrupt().
1282 ip2_polled_interrupt();
1284 mod_timer(&PollTimer, POLL_TIMEOUT);
1286 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1289 static void do_input(struct work_struct *work)
1291 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input);
1292 unsigned long flags;
1294 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1297 if ( pCh->pTTY != NULL ) {
1298 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1299 if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
1300 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1303 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1305 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1307 i2InputFlush( pCh );
1311 // code duplicated from n_tty (ldisc)
1312 static inline void isig(int sig, struct tty_struct *tty, int flush)
1314 /* FIXME: This is completely bogus */
1316 kill_pgrp(tty->pgrp, sig, 1);
1317 if (flush || !L_NOFLSH(tty)) {
1318 if ( tty->ldisc->ops->flush_buffer )
1319 tty->ldisc->ops->flush_buffer(tty);
1320 i2InputFlush( tty->driver_data );
1324 static void do_status(struct work_struct *work)
1326 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status);
1329 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1331 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1333 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1334 if ( (status & I2_BRK) ) {
1335 // code duplicated from n_tty (ldisc)
1336 if (I_IGNBRK(pCh->pTTY))
1338 if (I_BRKINT(pCh->pTTY)) {
1339 isig(SIGINT, pCh->pTTY, 1);
1342 wake_up_interruptible(&pCh->pTTY->read_wait);
1344 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1345 // and can't work because we don't know the_char
1346 // as the_char is reported on a separate path
1347 // The intelligent board does this stuff as setup
1349 char brkf = TTY_NORMAL;
1350 unsigned char brkc = '\0';
1352 if ( (status & I2_BRK) ) {
1356 else if (status & I2_PAR) {
1359 } else if (status & I2_FRA) {
1362 } else if (status & I2_OVR) {
1366 tmp = pCh->pTTY->real_raw;
1367 pCh->pTTY->real_raw = 0;
1368 pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1369 pCh->pTTY->real_raw = tmp;
1371 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1375 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1376 wake_up_interruptible(&pCh->delta_msr_wait);
1378 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1379 if ( status & I2_DCD ) {
1381 wake_up_interruptible ( &pCh->open_wait );
1384 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1385 tty_hangup( pCh->pTTY );
1391 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1394 /******************************************************************************/
1395 /* Device Open/Close/Ioctl Entry Point Section */
1396 /******************************************************************************/
1398 /******************************************************************************/
1399 /* Function: open_sanity_check() */
1400 /* Parameters: Pointer to tty structure */
1401 /* Pointer to file structure */
1402 /* Returns: Success or failure */
1405 /* Verifies the structure magic numbers and cross links. */
1406 /******************************************************************************/
1407 #ifdef IP2DEBUG_OPEN
1409 open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1411 if ( pBrd->i2eValid != I2E_MAGIC ) {
1412 printk(KERN_ERR "IP2: invalid board structure\n" );
1413 } else if ( pBrd != pCh->pMyBord ) {
1414 printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
1416 } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
1417 printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
1418 } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
1420 printk(KERN_INFO "IP2: all pointers check out!\n" );
1426 /******************************************************************************/
1427 /* Function: ip2_open() */
1428 /* Parameters: Pointer to tty structure */
1429 /* Pointer to file structure */
1430 /* Returns: Success or failure */
1432 /* Description: (MANDATORY) */
1433 /* A successful device open has to run a gauntlet of checks before it */
1434 /* completes. After some sanity checking and pointer setup, the function */
1435 /* blocks until all conditions are satisfied. It then initialises the port to */
1436 /* the default characteristics and returns. */
1437 /******************************************************************************/
1439 ip2_open( PTTY tty, struct file *pFile )
1444 i2ChanStrPtr pCh = DevTable[tty->index];
1446 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1448 if ( pCh == NULL ) {
1451 /* Setup pointer links in device and tty structures */
1453 tty->driver_data = pCh;
1455 #ifdef IP2DEBUG_OPEN
1457 "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
1458 tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
1459 open_sanity_check ( pCh, pCh->pMyBord );
1462 i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
1463 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1464 serviceOutgoingFifo( pCh->pMyBord );
1466 /* Block here until the port is ready (per serial and istallion) */
1468 * 1. If the port is in the middle of closing wait for the completion
1469 * and then return the appropriate error.
1471 init_waitqueue_entry(&wait, current);
1472 add_wait_queue(&pCh->close_wait, &wait);
1473 set_current_state( TASK_INTERRUPTIBLE );
1475 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1476 if ( pCh->flags & ASYNC_CLOSING ) {
1479 if ( tty_hung_up_p(pFile) ) {
1480 set_current_state( TASK_RUNNING );
1481 remove_wait_queue(&pCh->close_wait, &wait);
1482 return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
1485 set_current_state( TASK_RUNNING );
1486 remove_wait_queue(&pCh->close_wait, &wait);
1489 * 3. Handle a non-blocking open of a normal port.
1491 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1492 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1496 * 4. Now loop waiting for the port to be free and carrier present
1499 if ( tty->termios->c_cflag & CLOCAL )
1502 #ifdef IP2DEBUG_OPEN
1503 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1508 init_waitqueue_entry(&wait, current);
1509 add_wait_queue(&pCh->open_wait, &wait);
1512 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
1513 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1514 set_current_state( TASK_INTERRUPTIBLE );
1515 serviceOutgoingFifo( pCh->pMyBord );
1516 if ( tty_hung_up_p(pFile) ) {
1517 set_current_state( TASK_RUNNING );
1518 remove_wait_queue(&pCh->open_wait, &wait);
1519 return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
1521 if (!(pCh->flags & ASYNC_CLOSING) &&
1522 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1527 #ifdef IP2DEBUG_OPEN
1528 printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
1529 (pCh->flags & ASYNC_CLOSING)?"True":"False");
1530 printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
1532 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1533 (pCh->flags & ASYNC_CLOSING) );
1534 /* check for signal */
1535 if (signal_pending(current)) {
1536 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1541 set_current_state( TASK_RUNNING );
1542 remove_wait_queue(&pCh->open_wait, &wait);
1544 --pCh->wopen; //why count?
1546 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1551 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1555 /* first open - Assign termios structure to port */
1556 if ( tty->count == 1 ) {
1557 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1558 /* Now we must send the termios settings to the loadware */
1559 set_params( pCh, NULL );
1563 * Now set any i2lib options. These may go away if the i2lib code ends
1564 * up rolled into the mainline.
1566 pCh->channelOptions |= CO_NBLOCK_WRITE;
1568 #ifdef IP2DEBUG_OPEN
1569 printk (KERN_DEBUG "IP2: open completed\n" );
1571 serviceOutgoingFifo( pCh->pMyBord );
1573 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1578 /******************************************************************************/
1579 /* Function: ip2_close() */
1580 /* Parameters: Pointer to tty structure */
1581 /* Pointer to file structure */
1582 /* Returns: Nothing */
1587 /******************************************************************************/
1589 ip2_close( PTTY tty, struct file *pFile )
1591 i2ChanStrPtr pCh = tty->driver_data;
1597 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1599 #ifdef IP2DEBUG_OPEN
1600 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1603 if ( tty_hung_up_p ( pFile ) ) {
1605 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1609 if ( tty->count > 1 ) { /* not the last close */
1611 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1615 pCh->flags |= ASYNC_CLOSING; // last close actually
1619 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1621 * Before we drop DTR, make sure the transmitter has completely drained.
1622 * This uses an timeout, after which the close
1625 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1628 * At this point we stop accepting input. Here we flush the channel
1629 * input buffer which will allow the board to send up more data. Any
1630 * additional input is tossed at interrupt/poll time.
1632 i2InputFlush( pCh );
1634 /* disable DSS reporting */
1635 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1636 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1637 if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
1638 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1639 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1640 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1643 serviceOutgoingFifo ( pCh->pMyBord );
1645 tty_ldisc_flush(tty);
1646 tty_driver_flush_buffer(tty);
1652 if (pCh->ClosingDelay) {
1653 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1655 wake_up_interruptible(&pCh->open_wait);
1658 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1659 wake_up_interruptible(&pCh->close_wait);
1661 #ifdef IP2DEBUG_OPEN
1662 DBG_CNT("ip2_close: after wakeups--");
1666 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1671 /******************************************************************************/
1672 /* Function: ip2_hangup() */
1673 /* Parameters: Pointer to tty structure */
1674 /* Returns: Nothing */
1679 /******************************************************************************/
1681 ip2_hangup ( PTTY tty )
1683 i2ChanStrPtr pCh = tty->driver_data;
1689 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1691 ip2_flush_buffer(tty);
1693 /* disable DSS reporting */
1695 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1696 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1697 if ( (tty->termios->c_cflag & HUPCL) ) {
1698 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1699 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1700 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1702 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1703 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1704 serviceOutgoingFifo ( pCh->pMyBord );
1706 wake_up_interruptible ( &pCh->delta_msr_wait );
1708 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1710 wake_up_interruptible ( &pCh->open_wait );
1712 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1715 /******************************************************************************/
1716 /******************************************************************************/
1717 /* Device Output Section */
1718 /******************************************************************************/
1719 /******************************************************************************/
1721 /******************************************************************************/
1722 /* Function: ip2_write() */
1723 /* Parameters: Pointer to tty structure */
1724 /* Flag denoting data is in user (1) or kernel (0) space */
1725 /* Pointer to data */
1726 /* Number of bytes to write */
1727 /* Returns: Number of bytes actually written */
1729 /* Description: (MANDATORY) */
1732 /******************************************************************************/
1734 ip2_write( PTTY tty, const unsigned char *pData, int count)
1736 i2ChanStrPtr pCh = tty->driver_data;
1738 unsigned long flags;
1740 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1742 /* Flush out any buffered data left over from ip2_putchar() calls. */
1743 ip2_flush_chars( tty );
1745 /* This is the actual move bit. Make sure it does what we need!!!!! */
1746 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1747 bytesSent = i2Output( pCh, pData, count);
1748 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1750 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1752 return bytesSent > 0 ? bytesSent : 0;
1755 /******************************************************************************/
1756 /* Function: ip2_putchar() */
1757 /* Parameters: Pointer to tty structure */
1758 /* Character to write */
1759 /* Returns: Nothing */
1764 /******************************************************************************/
1766 ip2_putchar( PTTY tty, unsigned char ch )
1768 i2ChanStrPtr pCh = tty->driver_data;
1769 unsigned long flags;
1771 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1773 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1774 pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1775 if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
1776 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1777 ip2_flush_chars( tty );
1779 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1782 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1785 /******************************************************************************/
1786 /* Function: ip2_flush_chars() */
1787 /* Parameters: Pointer to tty structure */
1788 /* Returns: Nothing */
1792 /******************************************************************************/
1794 ip2_flush_chars( PTTY tty )
1797 i2ChanStrPtr pCh = tty->driver_data;
1798 unsigned long flags;
1800 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1801 if ( pCh->Pbuf_stuff ) {
1803 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1806 // We may need to restart i2Output if it does not fullfill this request
1808 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff);
1809 if ( strip != pCh->Pbuf_stuff ) {
1810 memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1812 pCh->Pbuf_stuff -= strip;
1814 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1817 /******************************************************************************/
1818 /* Function: ip2_write_room() */
1819 /* Parameters: Pointer to tty structure */
1820 /* Returns: Number of bytes that the driver can accept */
1824 /******************************************************************************/
1826 ip2_write_room ( PTTY tty )
1829 i2ChanStrPtr pCh = tty->driver_data;
1830 unsigned long flags;
1832 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1833 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1834 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1836 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1838 return ((bytesFree > 0) ? bytesFree : 0);
1841 /******************************************************************************/
1842 /* Function: ip2_chars_in_buf() */
1843 /* Parameters: Pointer to tty structure */
1844 /* Returns: Number of bytes queued for transmission */
1849 /******************************************************************************/
1851 ip2_chars_in_buf ( PTTY tty )
1853 i2ChanStrPtr pCh = tty->driver_data;
1855 unsigned long flags;
1857 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1859 #ifdef IP2DEBUG_WRITE
1860 printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1861 pCh->Obuf_char_count + pCh->Pbuf_stuff,
1862 pCh->Obuf_char_count, pCh->Pbuf_stuff );
1864 read_lock_irqsave(&pCh->Obuf_spinlock, flags);
1865 rc = pCh->Obuf_char_count;
1866 read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
1867 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1868 rc += pCh->Pbuf_stuff;
1869 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1873 /******************************************************************************/
1874 /* Function: ip2_flush_buffer() */
1875 /* Parameters: Pointer to tty structure */
1876 /* Returns: Nothing */
1881 /******************************************************************************/
1883 ip2_flush_buffer( PTTY tty )
1885 i2ChanStrPtr pCh = tty->driver_data;
1886 unsigned long flags;
1888 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1890 #ifdef IP2DEBUG_WRITE
1891 printk (KERN_DEBUG "IP2: flush buffer\n" );
1893 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1894 pCh->Pbuf_stuff = 0;
1895 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1896 i2FlushOutput( pCh );
1899 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1903 /******************************************************************************/
1904 /* Function: ip2_wait_until_sent() */
1905 /* Parameters: Pointer to tty structure */
1906 /* Timeout for wait. */
1907 /* Returns: Nothing */
1910 /* This function is used in place of the normal tty_wait_until_sent, which */
1911 /* only waits for the driver buffers to be empty (or rather, those buffers */
1912 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1913 /* indeterminate number of bytes buffered on the board. */
1914 /******************************************************************************/
1916 ip2_wait_until_sent ( PTTY tty, int timeout )
1919 i2ChanStrPtr pCh = tty->driver_data;
1921 tty_wait_until_sent(tty, timeout );
1922 if ( (i = timeout - (jiffies -i)) > 0)
1923 i2DrainOutput( pCh, i );
1926 /******************************************************************************/
1927 /******************************************************************************/
1928 /* Device Input Section */
1929 /******************************************************************************/
1930 /******************************************************************************/
1932 /******************************************************************************/
1933 /* Function: ip2_throttle() */
1934 /* Parameters: Pointer to tty structure */
1935 /* Returns: Nothing */
1940 /******************************************************************************/
1942 ip2_throttle ( PTTY tty )
1944 i2ChanStrPtr pCh = tty->driver_data;
1946 #ifdef IP2DEBUG_READ
1947 printk (KERN_DEBUG "IP2: throttle\n" );
1950 * Signal the poll/interrupt handlers not to forward incoming data to
1951 * the line discipline. This will cause the buffers to fill up in the
1952 * library and thus cause the library routines to send the flow control
1958 /******************************************************************************/
1959 /* Function: ip2_unthrottle() */
1960 /* Parameters: Pointer to tty structure */
1961 /* Returns: Nothing */
1966 /******************************************************************************/
1968 ip2_unthrottle ( PTTY tty )
1970 i2ChanStrPtr pCh = tty->driver_data;
1971 unsigned long flags;
1973 #ifdef IP2DEBUG_READ
1974 printk (KERN_DEBUG "IP2: unthrottle\n" );
1977 /* Pass incoming data up to the line discipline again. */
1979 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1980 serviceOutgoingFifo( pCh->pMyBord );
1981 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1982 if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
1983 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1984 #ifdef IP2DEBUG_READ
1985 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1989 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1993 ip2_start ( PTTY tty )
1995 i2ChanStrPtr pCh = DevTable[tty->index];
1997 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1998 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
1999 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
2000 #ifdef IP2DEBUG_WRITE
2001 printk (KERN_DEBUG "IP2: start tx\n" );
2006 ip2_stop ( PTTY tty )
2008 i2ChanStrPtr pCh = DevTable[tty->index];
2010 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
2011 #ifdef IP2DEBUG_WRITE
2012 printk (KERN_DEBUG "IP2: stop tx\n" );
2016 /******************************************************************************/
2017 /* Device Ioctl Section */
2018 /******************************************************************************/
2020 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2022 i2ChanStrPtr pCh = DevTable[tty->index];
2023 #ifdef ENABLE_DSSNOW
2031 FIXME - the following code is causing a NULL pointer dereference in
2032 2.3.51 in an interrupt handler. It's suppose to prompt the board
2033 to return the DSS signal status immediately. Why doesn't it do
2034 the same thing in 2.2.14?
2037 /* This thing is still busted in the 1.2.12 driver on 2.4.x
2038 and even hoses the serial console so the oops can be trapped.
2041 #ifdef ENABLE_DSSNOW
2042 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2044 init_waitqueue_entry(&wait, current);
2045 add_wait_queue(&pCh->dss_now_wait, &wait);
2046 set_current_state( TASK_INTERRUPTIBLE );
2048 serviceOutgoingFifo( pCh->pMyBord );
2052 set_current_state( TASK_RUNNING );
2053 remove_wait_queue(&pCh->dss_now_wait, &wait);
2055 if (signal_pending(current)) {
2059 return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2060 | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2061 | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0)
2062 | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0)
2063 | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0)
2064 | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0);
2067 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2068 unsigned int set, unsigned int clear)
2070 i2ChanStrPtr pCh = DevTable[tty->index];
2075 if (set & TIOCM_RTS) {
2076 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2077 pCh->dataSetOut |= I2_RTS;
2079 if (set & TIOCM_DTR) {
2080 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2081 pCh->dataSetOut |= I2_DTR;
2084 if (clear & TIOCM_RTS) {
2085 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2086 pCh->dataSetOut &= ~I2_RTS;
2088 if (clear & TIOCM_DTR) {
2089 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2090 pCh->dataSetOut &= ~I2_DTR;
2092 serviceOutgoingFifo( pCh->pMyBord );
2096 /******************************************************************************/
2097 /* Function: ip2_ioctl() */
2098 /* Parameters: Pointer to tty structure */
2099 /* Pointer to file structure */
2102 /* Returns: Success or failure */
2107 /******************************************************************************/
2109 ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2112 i2ChanStrPtr pCh = DevTable[tty->index];
2114 struct async_icount cprev, cnow; /* kernel counter temps */
2115 struct serial_icounter_struct __user *p_cuser;
2117 unsigned long flags;
2118 void __user *argp = (void __user *)arg;
2125 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2127 #ifdef IP2DEBUG_IOCTL
2128 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2134 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2136 rc = get_serial_info(pCh, argp);
2143 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2145 rc = set_serial_info(pCh, argp);
2151 rc = tty_check_change(tty);
2156 //return -ENOIOCTLCMD;
2159 //return -ENOIOCTLCMD;
2162 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2163 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2164 CMD_XMIT_NOW(STOP_CHAR(tty)));
2168 if (START_CHAR(tty) != __DISABLED_CHAR) {
2169 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2170 CMD_XMIT_NOW(START_CHAR(tty)));
2178 case TCSBRK: /* SVID version: non-zero arg --> no break */
2179 rc = tty_check_change(tty);
2181 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2184 ip2_wait_until_sent(tty,0);
2186 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2187 serviceOutgoingFifo( pCh->pMyBord );
2192 case TCSBRKP: /* support for POSIX tcsendbreak() */
2193 rc = tty_check_change(tty);
2195 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2198 ip2_wait_until_sent(tty,0);
2199 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2200 CMD_SEND_BRK(arg ? arg*100 : 250));
2201 serviceOutgoingFifo ( pCh->pMyBord );
2207 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2209 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2216 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2218 rc = get_user(arg,(unsigned long __user *) argp);
2221 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2222 | (arg ? CLOCAL : 0));
2227 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2228 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2229 * for masking). Caller should use TIOCGICOUNT to see which one it was
2232 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2233 cprev = pCh->icount; /* note the counters on entry */
2234 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2235 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
2236 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2237 init_waitqueue_entry(&wait, current);
2238 add_wait_queue(&pCh->delta_msr_wait, &wait);
2239 set_current_state( TASK_INTERRUPTIBLE );
2241 serviceOutgoingFifo( pCh->pMyBord );
2243 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2247 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2249 /* see if a signal did it */
2250 if (signal_pending(current)) {
2254 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2255 cnow = pCh->icount; /* atomic copy */
2256 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2257 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2258 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2259 rc = -EIO; /* no change => rc */
2262 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2263 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2264 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2265 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2271 set_current_state( TASK_RUNNING );
2272 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2274 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3,
2275 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2276 if ( ! (pCh->flags & ASYNC_CHECK_CD)) {
2277 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2279 serviceOutgoingFifo( pCh->pMyBord );
2284 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2285 * Return: write counters to the user passed counter struct
2286 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2287 * only 0->1 is counted. The controller is quite capable of counting
2288 * both, but this done to preserve compatibility with the standard
2292 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2294 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2296 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2298 rc = put_user(cnow.cts, &p_cuser->cts);
2299 rc = put_user(cnow.dsr, &p_cuser->dsr);
2300 rc = put_user(cnow.rng, &p_cuser->rng);
2301 rc = put_user(cnow.dcd, &p_cuser->dcd);
2302 rc = put_user(cnow.rx, &p_cuser->rx);
2303 rc = put_user(cnow.tx, &p_cuser->tx);
2304 rc = put_user(cnow.frame, &p_cuser->frame);
2305 rc = put_user(cnow.overrun, &p_cuser->overrun);
2306 rc = put_user(cnow.parity, &p_cuser->parity);
2307 rc = put_user(cnow.brk, &p_cuser->brk);
2308 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2312 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2313 * will be passed to the line discipline for it to handle.
2319 case TIOCSERGSTRUCT:
2320 case TIOCSERGETMULTI:
2321 case TIOCSERSETMULTI:
2324 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2330 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2335 /******************************************************************************/
2336 /* Function: GetSerialInfo() */
2337 /* Parameters: Pointer to channel structure */
2338 /* Pointer to old termios structure */
2339 /* Returns: Nothing */
2342 /* This is to support the setserial command, and requires processing of the */
2343 /* standard Linux serial structure. */
2344 /******************************************************************************/
2346 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2348 struct serial_struct tmp;
2350 memset ( &tmp, 0, sizeof(tmp) );
2351 tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2352 if (BID_HAS_654(tmp.type)) {
2353 tmp.type = PORT_16650;
2355 tmp.type = PORT_CIRRUS;
2357 tmp.line = pCh->port_index;
2358 tmp.port = pCh->pMyBord->i2eBase;
2359 tmp.irq = ip2config.irq[pCh->port_index/64];
2360 tmp.flags = pCh->flags;
2361 tmp.baud_base = pCh->BaudBase;
2362 tmp.close_delay = pCh->ClosingDelay;
2363 tmp.closing_wait = pCh->ClosingWaitTime;
2364 tmp.custom_divisor = pCh->BaudDivisor;
2365 return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2368 /******************************************************************************/
2369 /* Function: SetSerialInfo() */
2370 /* Parameters: Pointer to channel structure */
2371 /* Pointer to old termios structure */
2372 /* Returns: Nothing */
2375 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2376 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2377 /* change the IRQ, address or type of the port the ioctl fails. */
2378 /******************************************************************************/
2380 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2382 struct serial_struct ns;
2383 int old_flags, old_baud_divisor;
2385 if (copy_from_user(&ns, new_info, sizeof (ns)))
2389 * We don't allow setserial to change IRQ, board address, type or baud
2390 * base. Also line nunber as such is meaningless but we use it for our
2391 * array index so it is fixed also.
2393 if ( (ns.irq != ip2config.irq[pCh->port_index])
2394 || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase)))
2395 || (ns.baud_base != pCh->BaudBase)
2396 || (ns.line != pCh->port_index) ) {
2400 old_flags = pCh->flags;
2401 old_baud_divisor = pCh->BaudDivisor;
2403 if ( !capable(CAP_SYS_ADMIN) ) {
2404 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2405 ( (ns.flags & ~ASYNC_USR_MASK) !=
2406 (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2410 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2411 (ns.flags & ASYNC_USR_MASK);
2412 pCh->BaudDivisor = ns.custom_divisor;
2414 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2415 (ns.flags & ASYNC_FLAGS);
2416 pCh->BaudDivisor = ns.custom_divisor;
2417 pCh->ClosingDelay = ns.close_delay * HZ/100;
2418 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2421 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2422 || (old_baud_divisor != pCh->BaudDivisor) ) {
2423 // Invalidate speed and reset parameters
2424 set_params( pCh, NULL );
2430 /******************************************************************************/
2431 /* Function: ip2_set_termios() */
2432 /* Parameters: Pointer to tty structure */
2433 /* Pointer to old termios structure */
2434 /* Returns: Nothing */
2439 /******************************************************************************/
2441 ip2_set_termios( PTTY tty, struct ktermios *old_termios )
2443 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2445 #ifdef IP2DEBUG_IOCTL
2446 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2449 set_params( pCh, old_termios );
2452 /******************************************************************************/
2453 /* Function: ip2_set_line_discipline() */
2454 /* Parameters: Pointer to tty structure */
2455 /* Returns: Nothing */
2457 /* Description: Does nothing */
2460 /******************************************************************************/
2462 ip2_set_line_discipline ( PTTY tty )
2464 #ifdef IP2DEBUG_IOCTL
2465 printk (KERN_DEBUG "IP2: set line discipline\n" );
2468 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2472 /******************************************************************************/
2473 /* Function: SetLine Characteristics() */
2474 /* Parameters: Pointer to channel structure */
2475 /* Returns: Nothing */
2478 /* This routine is called to update the channel structure with the new line */
2479 /* characteristics, and send the appropriate commands to the board when they */
2481 /******************************************************************************/
2483 set_params( i2ChanStrPtr pCh, struct ktermios *o_tios )
2485 tcflag_t cflag, iflag, lflag;
2486 char stop_char, start_char;
2487 struct ktermios dummy;
2489 lflag = pCh->pTTY->termios->c_lflag;
2490 cflag = pCh->pTTY->termios->c_cflag;
2491 iflag = pCh->pTTY->termios->c_iflag;
2493 if (o_tios == NULL) {
2494 dummy.c_lflag = ~lflag;
2495 dummy.c_cflag = ~cflag;
2496 dummy.c_iflag = ~iflag;
2501 switch ( cflag & CBAUD ) {
2503 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2504 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2505 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2506 pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2511 * This is the speed that is overloaded with all the other high
2512 * speeds, depending upon the flag settings.
2514 if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2515 pCh->speed = CBR_57600;
2516 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2517 pCh->speed = CBR_115200;
2518 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2519 pCh->speed = CBR_C1;
2521 pCh->speed = CBR_38400;
2524 case B50: pCh->speed = CBR_50; break;
2525 case B75: pCh->speed = CBR_75; break;
2526 case B110: pCh->speed = CBR_110; break;
2527 case B134: pCh->speed = CBR_134; break;
2528 case B150: pCh->speed = CBR_150; break;
2529 case B200: pCh->speed = CBR_200; break;
2530 case B300: pCh->speed = CBR_300; break;
2531 case B600: pCh->speed = CBR_600; break;
2532 case B1200: pCh->speed = CBR_1200; break;
2533 case B1800: pCh->speed = CBR_1800; break;
2534 case B2400: pCh->speed = CBR_2400; break;
2535 case B4800: pCh->speed = CBR_4800; break;
2536 case B9600: pCh->speed = CBR_9600; break;
2537 case B19200: pCh->speed = CBR_19200; break;
2538 case B57600: pCh->speed = CBR_57600; break;
2539 case B115200: pCh->speed = CBR_115200; break;
2540 case B153600: pCh->speed = CBR_153600; break;
2541 case B230400: pCh->speed = CBR_230400; break;
2542 case B307200: pCh->speed = CBR_307200; break;
2543 case B460800: pCh->speed = CBR_460800; break;
2544 case B921600: pCh->speed = CBR_921600; break;
2545 default: pCh->speed = CBR_9600; break;
2547 if ( pCh->speed == CBR_C1 ) {
2548 // Process the custom speed parameters.
2549 int bps = pCh->BaudBase / pCh->BaudDivisor;
2550 if ( bps == 921600 ) {
2551 pCh->speed = CBR_921600;
2554 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2557 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2559 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2560 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2562 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2564 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2565 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2567 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2569 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2571 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2575 /* byte size and parity */
2576 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2579 switch ( cflag & CSIZE ) {
2580 case CS5: datasize = CSZ_5; break;
2581 case CS6: datasize = CSZ_6; break;
2582 case CS7: datasize = CSZ_7; break;
2583 case CS8: datasize = CSZ_8; break;
2584 default: datasize = CSZ_5; break; /* as per serial.c */
2586 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2588 /* Process CTS flow control flag setting */
2589 if ( (cflag & CRTSCTS) ) {
2590 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2591 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2593 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2594 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2597 // Process XON/XOFF flow control flags settings
2599 stop_char = STOP_CHAR(pCh->pTTY);
2600 start_char = START_CHAR(pCh->pTTY);
2602 //////////// can't be \000
2603 if (stop_char == __DISABLED_CHAR )
2605 stop_char = ~__DISABLED_CHAR;
2607 if (start_char == __DISABLED_CHAR )
2609 start_char = ~__DISABLED_CHAR;
2611 /////////////////////////////////
2613 if ( o_tios->c_cc[VSTART] != start_char )
2615 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2616 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2618 if ( o_tios->c_cc[VSTOP] != stop_char )
2620 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2621 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2623 if (stop_char == __DISABLED_CHAR )
2625 stop_char = ~__DISABLED_CHAR; //TEST123
2628 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2630 if ( iflag & IXOFF ) { // Enable XOFF output flow control
2631 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2632 } else { // Disable XOFF output flow control
2634 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2637 if (start_char == __DISABLED_CHAR )
2641 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2643 if ( iflag & IXON ) {
2644 if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2645 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2646 } else { // Enable XON output flow control
2647 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2649 } else { // Disable XON output flow control
2651 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2654 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2656 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2657 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2659 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2661 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2662 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2665 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2666 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2671 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2672 /* Ignore breaks altogether */
2673 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2675 if ( iflag & BRKINT ) {
2676 if ( iflag & PARMRK ) {
2677 brkrpt = 0x0a; // exception an inline triple
2679 brkrpt = 0x1a; // exception and NULL
2681 brkrpt |= 0x04; // flush input
2683 if ( iflag & PARMRK ) {
2684 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2686 brkrpt = 0x01; // Null only
2689 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2692 if (iflag & IGNPAR) {
2694 /* would be 2 for not cirrus bug */
2695 /* would be 0x20 cept for cirrus bug */
2697 if ( iflag & PARMRK ) {
2699 * Replace error characters with 3-byte sequence (\0377,\0,char)
2702 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2707 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2709 if (cflag & CLOCAL) {
2710 // Status reporting fails for DCD if this is off
2711 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2712 pCh->flags &= ~ASYNC_CHECK_CD;
2714 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2715 pCh->flags |= ASYNC_CHECK_CD;
2719 i2DrainOutput( pCh, 100 );
2722 /******************************************************************************/
2723 /* IPL Device Section */
2724 /******************************************************************************/
2726 /******************************************************************************/
2727 /* Function: ip2_ipl_read() */
2728 /* Parameters: Pointer to device inode */
2729 /* Pointer to file structure */
2730 /* Pointer to data */
2731 /* Number of bytes to read */
2732 /* Returns: Success or failure */
2734 /* Description: Ugly */
2737 /******************************************************************************/
2741 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2743 unsigned int minor = iminor(pFile->f_path.dentry->d_inode);
2747 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2751 case 0: // IPL device
2754 case 1: // Status dump
2757 case 2: // Ping device
2760 case 3: // Trace device
2761 rc = DumpTraceBuffer ( pData, count );
2763 case 4: // Trace device
2764 rc = DumpFifoBuffer ( pData, count );
2774 DumpFifoBuffer ( char __user *pData, int count )
2778 rc = copy_to_user(pData, DBGBuf, count);
2780 printk(KERN_DEBUG "Last index %d\n", I );
2783 #endif /* DEBUG_FIFO */
2788 DumpTraceBuffer ( char __user *pData, int count )
2790 #ifdef IP2DEBUG_TRACE
2794 int *pIndex = (int __user *)pData;
2796 if ( count < (sizeof(int) * 6) ) {
2799 rc = put_user(tracewrap, pIndex );
2800 rc = put_user(TRACEMAX, ++pIndex );
2801 rc = put_user(tracestrip, ++pIndex );
2802 rc = put_user(tracestuff, ++pIndex );
2803 pData += sizeof(int) * 6;
2804 count -= sizeof(int) * 6;
2806 dumpcount = tracestuff - tracestrip;
2807 if ( dumpcount < 0 ) {
2808 dumpcount += TRACEMAX;
2810 if ( dumpcount > count ) {
2813 chunk = TRACEMAX - tracestrip;
2814 if ( dumpcount > chunk ) {
2815 rc = copy_to_user(pData, &tracebuf[tracestrip],
2816 chunk * sizeof(tracebuf[0]) );
2817 pData += chunk * sizeof(tracebuf[0]);
2819 chunk = dumpcount - chunk;
2823 rc = copy_to_user(pData, &tracebuf[tracestrip],
2824 chunk * sizeof(tracebuf[0]) );
2825 tracestrip += chunk;
2828 rc = put_user(tracestrip, ++pIndex );
2829 rc = put_user(tracestuff, ++pIndex );
2837 /******************************************************************************/
2838 /* Function: ip2_ipl_write() */
2840 /* Pointer to file structure */
2841 /* Pointer to data */
2842 /* Number of bytes to write */
2843 /* Returns: Success or failure */
2848 /******************************************************************************/
2850 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2853 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2858 /******************************************************************************/
2859 /* Function: ip2_ipl_ioctl() */
2860 /* Parameters: Pointer to device inode */
2861 /* Pointer to file structure */
2864 /* Returns: Success or failure */
2869 /******************************************************************************/
2871 ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
2873 unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode);
2875 void __user *argp = (void __user *)arg;
2876 ULONG __user *pIndex = argp;
2877 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2881 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2886 switch ( iplminor ) {
2887 case 0: // IPL device
2890 case 1: // Status dump
2895 case 64: /* Driver - ip2stat */
2896 rc = put_user(-1, pIndex++ );
2897 rc = put_user(irq_counter, pIndex++ );
2898 rc = put_user(bh_counter, pIndex++ );
2901 case 65: /* Board - ip2stat */
2903 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
2904 rc = put_user(inb(pB->i2eStatus),
2905 (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2912 if (cmd < IP2_MAX_PORTS) {
2913 pCh = DevTable[cmd];
2916 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2926 case 2: // Ping device
2929 case 3: // Trace device
2931 * akpm: This used to write a whole bunch of function addresses
2932 * to userspace, which generated lots of put_user() warnings.
2933 * I killed it all. Just return "success" and don't do
2950 /******************************************************************************/
2951 /* Function: ip2_ipl_open() */
2952 /* Parameters: Pointer to device inode */
2953 /* Pointer to file structure */
2954 /* Returns: Success or failure */
2959 /******************************************************************************/
2961 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2965 printk (KERN_DEBUG "IP2IPL: open\n" );
2967 cycle_kernel_lock();
2972 proc_ip2mem_show(struct seq_file *m, void *v)
2979 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
2980 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
2981 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
2985 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
2986 pB = i2BoardPtrTable[i];
2988 seq_printf(m,"board %d:\n",i);
2989 seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n",
2990 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
2994 seq_printf(m,"#: tty flags, port flags, cflags, iflags\n");
2995 for (i=0; i < IP2_MAX_PORTS; i++) {
2999 if (tty && tty->count) {
3000 seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags,
3001 tty->termios->c_cflag,tty->termios->c_iflag);
3003 seq_printf(m,FMTLIN2,
3004 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
3005 seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room);
3012 static int proc_ip2mem_open(struct inode *inode, struct file *file)
3014 return single_open(file, proc_ip2mem_show, NULL);
3017 static const struct file_operations ip2mem_proc_fops = {
3018 .owner = THIS_MODULE,
3019 .open = proc_ip2mem_open,
3021 .llseek = seq_lseek,
3022 .release = single_release,
3026 * This is the handler for /proc/tty/driver/ip2
3028 * This stretch of code has been largely plagerized from at least three
3029 * different sources including ip2mkdev.c and a couple of other drivers.
3030 * The bugs are all mine. :-) =mhw=
3032 static int ip2_proc_show(struct seq_file *m, void *v)
3041 seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
3042 seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3043 IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3044 IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3046 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3047 /* This need to be reset for a board by board count... */
3049 pB = i2BoardPtrTable[i];
3051 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3054 seq_printf(m, "Board %d: EX ports=", i);
3056 for( box = 0; box < ABS_MAX_BOXES; ++box )
3060 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3061 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3063 if( pB->i2eChannelMap[box] & 1<< j ) {
3067 seq_printf(m, "%s%d", sep, ports);
3071 seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
3075 seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
3080 seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
3085 seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
3090 seq_printf(m, "Board %d: unknown", i);
3091 /* Don't try and probe for minor numbers */
3096 /* Don't try and probe for minor numbers */
3097 seq_printf(m, "Board %d: vacant", i);
3102 seq_puts(m, " minors=");
3104 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3106 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3108 if ( pB->i2eChannelMap[box] & (1 << j) )
3110 seq_printf(m, "%s%d", sep,
3111 j + ABS_BIGGEST_BOX *
3112 (box+i*ABS_MAX_BOXES));
3123 static int ip2_proc_open(struct inode *inode, struct file *file)
3125 return single_open(file, ip2_proc_show, NULL);
3128 static const struct file_operations ip2_proc_fops = {
3129 .owner = THIS_MODULE,
3130 .open = ip2_proc_open,
3132 .llseek = seq_lseek,
3133 .release = single_release,
3136 /******************************************************************************/
3137 /* Function: ip2trace() */
3138 /* Parameters: Value to add to trace buffer */
3139 /* Returns: Nothing */
3144 /******************************************************************************/
3145 #ifdef IP2DEBUG_TRACE
3147 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3150 unsigned long *pCode = &codes;
3151 union ip2breadcrumb bc;
3155 tracebuf[tracestuff++] = jiffies;
3156 if ( tracestuff == TRACEMAX ) {
3159 if ( tracestuff == tracestrip ) {
3160 if ( ++tracestrip == TRACEMAX ) {
3166 bc.hdr.port = 0xff & pn;
3168 bc.hdr.codes = (unsigned char)( codes & 0xff );
3169 bc.hdr.label = label;
3170 tracebuf[tracestuff++] = bc.value;
3173 if ( tracestuff == TRACEMAX ) {
3176 if ( tracestuff == tracestrip ) {
3177 if ( ++tracestrip == TRACEMAX ) {
3186 tracebuf[tracestuff++] = *++pCode;
3192 MODULE_LICENSE("GPL");
3194 static struct pci_device_id ip2main_pci_tbl[] __devinitdata = {
3195 { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) },
3199 MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);