1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86#include <linux/ctype.h>
87#include <linux/string.h>
88#include <linux/fcntl.h>
89#include <linux/errno.h>
90#include <linux/module.h>
91#include <linux/signal.h>
92#include <linux/sched.h>
93#include <linux/timer.h>
94#include <linux/interrupt.h>
95#include <linux/pci.h>
96#include <linux/mm.h>
97#include <linux/slab.h>
98#include <linux/major.h>
99#include <linux/wait.h>
100#include <linux/device.h>
101#include <linux/smp_lock.h>
102#include <linux/firmware.h>
103#include <linux/platform_device.h>
104
105#include <linux/tty.h>
106#include <linux/tty_flip.h>
107#include <linux/termios.h>
108#include <linux/tty_driver.h>
109#include <linux/serial.h>
110#include <linux/ptrace.h>
111#include <linux/ioport.h>
112
113#include <linux/cdk.h>
114#include <linux/comstats.h>
115#include <linux/delay.h>
116#include <linux/bitops.h>
117
118#include <asm/system.h>
119#include <asm/io.h>
120#include <asm/irq.h>
121
122#include <linux/vmalloc.h>
123#include <linux/init.h>
124
125#include <asm/uaccess.h>
126
127#include "ip2types.h"
128#include "ip2trace.h"
129#include "ip2ioctl.h"
130#include "ip2.h"
131#include "i2ellis.h"
132#include "i2lib.h"
133
134
135
136
137
138#include <linux/proc_fs.h>
139#include <linux/seq_file.h>
140
141static const struct file_operations ip2mem_proc_fops;
142static const struct file_operations ip2_proc_fops;
143
144
145
146
147
148
149
150
151
152
153static const char pcName[] = "Computone IntelliPort Plus multiport driver";
154static const char pcVersion[] = "1.2.14";
155
156
157static const char pcDriver_name[] = "ip2";
158static const char pcIpl[] = "ip2ipl";
159
160
161
162
163
164
165
166
167static int ip2_open(PTTY, struct file *);
168static void ip2_close(PTTY, struct file *);
169static int ip2_write(PTTY, const unsigned char *, int);
170static int ip2_putchar(PTTY, unsigned char);
171static void ip2_flush_chars(PTTY);
172static int ip2_write_room(PTTY);
173static int ip2_chars_in_buf(PTTY);
174static void ip2_flush_buffer(PTTY);
175static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
176static void ip2_set_termios(PTTY, struct ktermios *);
177static void ip2_set_line_discipline(PTTY);
178static void ip2_throttle(PTTY);
179static void ip2_unthrottle(PTTY);
180static void ip2_stop(PTTY);
181static void ip2_start(PTTY);
182static void ip2_hangup(PTTY);
183static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
184static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
185 unsigned int set, unsigned int clear);
186
187static void set_irq(int, int);
188static void ip2_interrupt_bh(struct work_struct *work);
189static irqreturn_t ip2_interrupt(int irq, void *dev_id);
190static void ip2_poll(unsigned long arg);
191static inline void service_all_boards(void);
192static void do_input(struct work_struct *);
193static void do_status(struct work_struct *);
194
195static void ip2_wait_until_sent(PTTY,int);
196
197static void set_params (i2ChanStrPtr, struct ktermios *);
198static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
199static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
200
201static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
202static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
203static long ip2_ipl_ioctl(struct file *, UINT, ULONG);
204static int ip2_ipl_open(struct inode *, struct file *);
205
206static int DumpTraceBuffer(char __user *, int);
207static int DumpFifoBuffer( char __user *, int);
208
209static void ip2_init_board(int, const struct firmware *);
210static unsigned short find_eisa_board(int);
211
212
213
214
215
216static struct tty_driver *ip2_tty_driver;
217
218
219
220
221static unsigned short i2nBoards;
222
223static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
224
225static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
226
227static void *DevTableMem[IP2_MAX_BOARDS];
228
229
230
231
232static 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,
238};
239
240static unsigned long irq_counter;
241static unsigned long bh_counter;
242
243
244#define USE_IQI
245
246
247
248
249
250#define POLL_TIMEOUT (jiffies + 1)
251static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
252
253#ifdef IP2DEBUG_TRACE
254
255#define TRACEMAX 1000
256static unsigned long tracebuf[TRACEMAX];
257static int tracestuff;
258static int tracestrip;
259static int tracewrap;
260#endif
261
262
263
264
265
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,0,s)
270#else
271#define DBG_CNT(s)
272#endif
273
274
275
276
277
278#include "i2ellis.c"
279#include "i2cmd.c"
280#include "i2lib.c"
281
282
283
284MODULE_AUTHOR("Doug McNash");
285MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
286MODULE_LICENSE("GPL");
287
288static int poll_only;
289
290static int Eisa_irq;
291static int Eisa_slot;
292
293static int iindx;
294static char rirqs[IP2_MAX_BOARDS];
295static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
296
297
298
299
300
301static int io[IP2_MAX_BOARDS];
302static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 };
303
304MODULE_AUTHOR("Doug McNash");
305MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
306module_param_array(irq, int, NULL, 0);
307MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards");
308module_param_array(io, int, NULL, 0);
309MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards");
310module_param(poll_only, bool, 0);
311MODULE_PARM_DESC(poll_only, "Do not use card interrupts");
312
313
314static struct class *ip2_class;
315
316
317
318static int __init is_valid_irq(int irq)
319{
320 int *i = Valid_Irqs;
321
322 while (*i != 0 && *i != irq)
323 i++;
324
325 return *i;
326}
327
328static void __init mark_requested_irq(char irq)
329{
330 rirqs[iindx++] = irq;
331}
332
333static int __exit clear_requested_irq(char irq)
334{
335 int i;
336 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
337 if (rirqs[i] == irq) {
338 rirqs[i] = 0;
339 return 1;
340 }
341 }
342 return 0;
343}
344
345static int have_requested_irq(char irq)
346{
347
348
349 int i;
350 for (i = 0; i < IP2_MAX_BOARDS; ++i)
351 if (rirqs[i] == irq)
352 return 1;
353 return 0;
354}
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371static void __exit ip2_cleanup_module(void)
372{
373 int err;
374 int i;
375
376 del_timer_sync(&PollTimer);
377
378
379 for (i = 0; i < IP2_MAX_BOARDS; i++)
380 if (i2BoardPtrTable[i])
381 iiReset(i2BoardPtrTable[i]);
382
383
384 for (i = 0; i < IP2_MAX_BOARDS; i++) {
385 if (i2BoardPtrTable[i]) {
386 iiResetDelay(i2BoardPtrTable[i]);
387
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,
391 4 * i + 1));
392 }
393
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]);
398 }
399 }
400 class_destroy(ip2_class);
401 err = tty_unregister_driver(ip2_tty_driver);
402 if (err)
403 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n",
404 err);
405 put_tty_driver(ip2_tty_driver);
406 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
407 remove_proc_entry("ip2mem", NULL);
408
409
410 for (i = 0; i < IP2_MAX_BOARDS; i++) {
411 void *pB;
412#ifdef CONFIG_PCI
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;
417 }
418#endif
419 pB = i2BoardPtrTable[i];
420 if (pB != NULL) {
421 kfree(pB);
422 i2BoardPtrTable[i] = NULL;
423 }
424 if (DevTableMem[i] != NULL) {
425 kfree(DevTableMem[i]);
426 DevTableMem[i] = NULL;
427 }
428 }
429}
430module_exit(ip2_cleanup_module);
431
432static const struct tty_operations ip2_ops = {
433 .open = ip2_open,
434 .close = ip2_close,
435 .write = ip2_write,
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,
441 .ioctl = ip2_ioctl,
442 .throttle = ip2_throttle,
443 .unthrottle = ip2_unthrottle,
444 .set_termios = ip2_set_termios,
445 .set_ldisc = ip2_set_line_discipline,
446 .stop = ip2_stop,
447 .start = ip2_start,
448 .hangup = ip2_hangup,
449 .tiocmget = ip2_tiocmget,
450 .tiocmset = ip2_tiocmset,
451 .proc_fops = &ip2_proc_fops,
452};
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469#define IP2_SA_FLAGS 0
470
471
472static const struct firmware *ip2_request_firmware(void)
473{
474 struct platform_device *pdev;
475 const struct firmware *fw;
476
477 pdev = platform_device_register_simple("ip2", 0, NULL, 0);
478 if (IS_ERR(pdev)) {
479 printk(KERN_ERR "Failed to register platform device for ip2\n");
480 return NULL;
481 }
482 if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) {
483 printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n");
484 fw = NULL;
485 }
486 platform_device_unregister(pdev);
487 return fw;
488}
489
490#ifndef MODULE
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512static int __init ip2_setup(char *str)
513{
514 int j, ints[10];
515 unsigned int i;
516
517 str = get_options(str, ARRAY_SIZE(ints), ints);
518
519 for (i = 0, j = 1; i < 4; i++) {
520 if (j > ints[0])
521 break;
522 if (ints[j] >= 0)
523 io[i] = ints[j];
524 j++;
525 if (j > ints[0])
526 break;
527 if (ints[j] >= 0)
528 irq[i] = ints[j];
529 j++;
530 }
531 return 1;
532}
533__setup("ip2=", ip2_setup);
534#endif
535
536static int __init ip2_loadmain(void)
537{
538 int i, j, box;
539 int err = 0;
540 i2eBordStrPtr pB = NULL;
541 int rc = -1;
542 struct pci_dev *pdev = NULL;
543 const struct firmware *fw = NULL;
544
545 if (poll_only) {
546
547 irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0;
548 }
549
550 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0);
551
552
553
554
555
556 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
557 ip2config.addr[i] = io[i];
558 if (irq[i] >= 0)
559 ip2config.irq[i] = irq[i];
560 else
561 ip2config.irq[i] = 0;
562
563
564
565
566
567
568
569
570
571
572
573
574 poll_only |= irq[i];
575 }
576 poll_only = !poll_only;
577
578
579 printk(KERN_INFO "%s version %s\n", pcName, pcVersion);
580
581 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
582 if (!ip2_tty_driver)
583 return -ENOMEM;
584
585
586 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
587 switch (ip2config.addr[i]) {
588 case 0:
589 break;
590 default:
591
592 if (ip2config.addr[i] < 0x100 ||
593 ip2config.addr[i] > 0x3f8) {
594 printk(KERN_ERR "IP2: Bad ISA board %d "
595 "address %x\n", i,
596 ip2config.addr[i]);
597 ip2config.addr[i] = 0;
598 break;
599 }
600 ip2config.type[i] = ISA;
601
602
603
604 if (ip2config.irq[i] &&
605 !is_valid_irq(ip2config.irq[i])) {
606 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",
607 ip2config.irq[i]);
608
609 ip2config.irq[i] = 0;
610 }
611 break;
612 case PCI:
613#ifdef CONFIG_PCI
614 {
615 u32 addr;
616 int status;
617
618 pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
619 PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev);
620 if (pdev == NULL) {
621 ip2config.addr[i] = 0;
622 printk(KERN_ERR "IP2: PCI board %d not "
623 "found\n", i);
624 break;
625 }
626
627 if (pci_enable_device(pdev)) {
628 dev_err(&pdev->dev, "can't enable device\n");
629 break;
630 }
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,
634 &addr);
635 if (addr & 1)
636 ip2config.addr[i] = (USHORT)(addr & 0xfffe);
637 else
638 dev_err(&pdev->dev, "I/O address error\n");
639
640 ip2config.irq[i] = pdev->irq;
641 }
642#else
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 "
646 "defined!\n");
647#endif
648 break;
649 case EISA:
650 ip2config.addr[i] = find_eisa_board(Eisa_slot + 1);
651 if (ip2config.addr[i] != 0) {
652
653 ip2config.type[i] = EISA;
654 }
655 ip2config.irq[i] = Eisa_irq;
656 break;
657 }
658 }
659 pci_dev_put(pdev);
660
661 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
662 if (ip2config.addr[i]) {
663 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
664 if (pB) {
665 i2BoardPtrTable[i] = pB;
666 iiSetAddress(pB, ip2config.addr[i],
667 ii2DelayTimer);
668 iiReset(pB);
669 } else
670 printk(KERN_ERR "IP2: board memory allocation "
671 "error\n");
672 }
673 }
674 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
675 pB = i2BoardPtrTable[i];
676 if (pB != NULL) {
677 iiResetDelay(pB);
678 break;
679 }
680 }
681 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
682
683
684 if (i2BoardPtrTable[i] != NULL) {
685 if (!fw)
686 fw = ip2_request_firmware();
687 if (!fw)
688 break;
689 ip2_init_board(i, fw);
690 }
691 }
692 if (fw)
693 release_firmware(fw);
694
695 ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0);
696
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);
709
710 ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0);
711
712 err = tty_register_driver(ip2_tty_driver);
713 if (err) {
714 printk(KERN_ERR "IP2: failed to register tty driver\n");
715 put_tty_driver(ip2_tty_driver);
716 return err;
717 }
718
719 err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl);
720 if (err) {
721 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n",
722 err);
723 } else {
724
725 ip2_class = class_create(THIS_MODULE, "ip2");
726 if (IS_ERR(ip2_class)) {
727 err = PTR_ERR(ip2_class);
728 goto out_chrdev;
729 }
730 }
731
732 if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) {
733 printk(KERN_ERR "IP2: failed to register read_procmem\n");
734 return -EIO;
735 }
736
737 ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0);
738
739
740
741
742 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
743 if (ip2config.addr[i] == 0)
744 continue;
745
746 pB = i2BoardPtrTable[i];
747 if (pB != NULL) {
748 device_create(ip2_class, NULL,
749 MKDEV(IP2_IPL_MAJOR, 4 * i),
750 NULL, "ipl%d", i);
751 device_create(ip2_class, NULL,
752 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
753 NULL, "stat%d", i);
754
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))
758 tty_register_device(
759 ip2_tty_driver,
760 j + ABS_BIGGEST_BOX *
761 (box+i*ABS_MAX_BOXES),
762 NULL);
763 }
764
765 if (poll_only) {
766
767
768 ip2config.irq[i] = CIR_POLL;
769 }
770 if (ip2config.irq[i] == CIR_POLL) {
771retry:
772 if (!timer_pending(&PollTimer)) {
773 mod_timer(&PollTimer, POLL_TIMEOUT);
774 printk(KERN_INFO "IP2: polling\n");
775 }
776 } else {
777 if (have_requested_irq(ip2config.irq[i]))
778 continue;
779 rc = request_irq(ip2config.irq[i], ip2_interrupt,
780 IP2_SA_FLAGS |
781 (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
782 pcName, i2BoardPtrTable[i]);
783 if (rc) {
784 printk(KERN_ERR "IP2: request_irq failed: "
785 "error %d\n", rc);
786 ip2config.irq[i] = CIR_POLL;
787 printk(KERN_INFO "IP2: Polling %ld/sec.\n",
788 (POLL_TIMEOUT - jiffies));
789 goto retry;
790 }
791 mark_requested_irq(ip2config.irq[i]);
792
793
794 }
795 }
796
797 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
798 if (i2BoardPtrTable[i]) {
799
800 set_irq(i, ip2config.irq[i]);
801 }
802 }
803
804 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0);
805
806 return 0;
807
808out_chrdev:
809 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
810
811 return err;
812}
813module_init(ip2_loadmain);
814
815
816
817
818
819
820
821
822
823
824
825static void
826ip2_init_board(int boardnum, const struct firmware *fw)
827{
828 int i;
829 int nports = 0, nboxes = 0;
830 i2ChanStrPtr pCh;
831 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
832
833 if ( !iiInitialize ( pB ) ) {
834 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
835 pB->i2eBase, pB->i2eError );
836 goto err_initialize;
837 }
838 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
839 ip2config.addr[boardnum], ip2config.irq[boardnum] );
840
841 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
842 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
843 goto err_initialize;
844 }
845
846 if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size )
847 != II_DOWN_GOOD ) {
848 printk ( KERN_ERR "IP2: failed to download loadware\n" );
849 goto err_release_region;
850 } else {
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 );
856 }
857
858 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
859
860 default:
861 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
862 pB->i2ePom.e.porID );
863 nports = 0;
864 goto err_release_region;
865 break;
866
867 case POR_ID_II_4:
868 printk ( KERN_INFO "IP2: ISA-4\n" );
869 nports = 4;
870 break;
871
872 case POR_ID_II_8:
873 printk ( KERN_INFO "IP2: ISA-8 std\n" );
874 nports = 8;
875 break;
876
877 case POR_ID_II_8R:
878 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
879 nports = 8;
880 break;
881
882 case POR_ID_FIIEX:
883 {
884 int portnum = IP2_PORTS_PER_BOARD * boardnum;
885 int box;
886
887 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
888 if ( pB->i2eChannelMap[box] != 0 ) {
889 ++nboxes;
890 }
891 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
892 if ( pB->i2eChannelMap[box] & 1<< i ) {
893 ++nports;
894 }
895 }
896 }
897 DevTableMem[boardnum] = pCh =
898 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
899 if ( !pCh ) {
900 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
901 goto err_release_region;
902 }
903 if ( !i2InitChannels( pB, nports, pCh ) ) {
904 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
905 kfree ( pCh );
906 goto err_release_region;
907 }
908 pB->i2eChannelPtr = &DevTable[portnum];
909 pB->i2eChannelCnt = ABS_MOST_PORTS;
910
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;
916 pCh++;
917 }
918 }
919 }
920 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
921 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
922 }
923 goto ex_exit;
924 }
925 DevTableMem[boardnum] = pCh =
926 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
927 if ( !pCh ) {
928 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
929 goto err_release_region;
930 }
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);
935 kfree ( pCh );
936 goto err_release_region;
937 }
938 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
939
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;
943 pCh++;
944 }
945ex_exit:
946 INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh);
947 return;
948
949err_release_region:
950 release_region(ip2config.addr[boardnum], 8);
951err_initialize:
952 kfree ( pB );
953 i2BoardPtrTable[boardnum] = NULL;
954 return;
955}
956
957
958
959
960
961
962
963
964
965
966
967
968static unsigned short
969find_eisa_board( int start_slot )
970{
971 int i, j;
972 unsigned int idm = 0;
973 unsigned int idp = 0;
974 unsigned int base = 0;
975 unsigned int value;
976 int setup_address;
977 int setup_irq;
978 int ismine = 0;
979
980
981
982
983
984
985
986
987 i = 0x0c80;
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);
991 if ( value == j )
992 return 0;
993 }
994
995
996
997
998
999 for( i = start_slot; i < 16; i++ ) {
1000 base = i << 12;
1001 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
1002 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
1003 ismine = 0;
1004 if ( idm == 0x0e8e ) {
1005 if ( idp == 0x0281 || idp == 0x0218 ) {
1006 ismine = 1;
1007 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1008 ismine = 3;
1009 }
1010 if ( ismine ) {
1011 Eisa_slot = i;
1012 break;
1013 }
1014 }
1015 }
1016 if ( !ismine )
1017 return 0;
1018
1019
1020
1021 setup_address = base + 0xc88;
1022 value = inb(base + 0xc86);
1023 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1024
1025 if ( (ismine & 2) && !(value & 0x10) ) {
1026 ismine = 1;
1027 }
1028
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" );
1033 }
1034
1035#ifdef IP2DEBUG_INIT
1036printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1037 base >> 12, idm, idp, setup_address);
1038 if ( Eisa_irq ) {
1039 printk(KERN_DEBUG ", Interrupt %d %s\n",
1040 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1041 } else {
1042 printk(KERN_DEBUG ", (polled)\n");
1043 }
1044#endif
1045 return setup_address;
1046}
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056static void
1057set_irq( int boardnum, int boardIrq )
1058{
1059 unsigned char tempCommand[16];
1060 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1061 unsigned long flags;
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074 iiDisableMailIrq(pB);
1075
1076
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;
1082
1083
1084
1085
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;
1091
1092
1093 ++i2nBoards;
1094
1095 CHANNEL_OF(tempCommand) = 0;
1096 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1097 CMD_COUNT_OF(tempCommand) = 6;
1098 (CMD_OF(tempCommand))[0] = 88;
1099 (CMD_OF(tempCommand))[1] = 64;
1100 (CMD_OF(tempCommand))[2] = 32;
1101
1102 (CMD_OF(tempCommand))[3] = 28;
1103 (CMD_OF(tempCommand))[4] = 64;
1104
1105 (CMD_OF(tempCommand))[5] = 87;
1106 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1107 iiWriteBuf(pB, tempCommand, 8);
1108 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1109
1110 CHANNEL_OF(tempCommand) = 0;
1111 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1112 CMD_COUNT_OF(tempCommand) = 1;
1113 (CMD_OF(tempCommand))[0] = 84;
1114 iiWriteBuf(pB, tempCommand, 3);
1115
1116#ifdef XXX
1117
1118 CHANNEL_OF(tempCommand) = 0;
1119 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1120 CMD_COUNT_OF(tempCommand) = 2;
1121 (CMD_OF(tempCommand))[0] = 44;
1122 (CMD_OF(tempCommand))[1] = 200;
1123 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1124 iiWriteBuf(pB, tempCommand, 4);
1125 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1126#endif
1127
1128 iiEnableMailIrq(pB);
1129 iiSendPendingMail(pB);
1130}
1131
1132
1133
1134
1135
1136static inline void
1137service_all_boards(void)
1138{
1139 int i;
1140 i2eBordStrPtr pB;
1141
1142
1143 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1144 pB = i2BoardPtrTable[i];
1145 if ( pB ) {
1146 i2ServiceBoard( pB );
1147 }
1148 }
1149}
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162static void
1163ip2_interrupt_bh(struct work_struct *work)
1164{
1165 i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt);
1166
1167
1168
1169
1170 bh_counter++;
1171
1172 if ( pB ) {
1173 i2ServiceBoard( pB );
1174 if( pB->i2eUsingIrq ) {
1175
1176 iiEnableMailIrq(pB);
1177 }
1178 }
1179}
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200static void
1201ip2_irq_work(i2eBordStrPtr pB)
1202{
1203#ifdef USE_IQI
1204 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1205
1206
1207 iiDisableMailIrq(pB);
1208
1209
1210 schedule_work(&pB->tqueue_interrupt);
1211
1212
1213 }
1214#else
1215
1216
1217
1218
1219
1220 i2ServiceBoard( pB );
1221
1222#endif
1223}
1224
1225static void
1226ip2_polled_interrupt(void)
1227{
1228 int i;
1229 i2eBordStrPtr pB;
1230
1231 ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0);
1232
1233
1234 for( i = 0; i < i2nBoards; ++i ) {
1235 pB = i2BoardPtrTable[i];
1236
1237
1238
1239
1240 if (pB && pB->i2eUsingIrq == 0)
1241 ip2_irq_work(pB);
1242 }
1243
1244 ++irq_counter;
1245
1246 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1247}
1248
1249static irqreturn_t
1250ip2_interrupt(int irq, void *dev_id)
1251{
1252 i2eBordStrPtr pB = dev_id;
1253
1254 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq );
1255
1256 ip2_irq_work(pB);
1257
1258 ++irq_counter;
1259
1260 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1261 return IRQ_HANDLED;
1262}
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274static void
1275ip2_poll(unsigned long arg)
1276{
1277 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1278
1279
1280
1281
1282 ip2_polled_interrupt();
1283
1284 mod_timer(&PollTimer, POLL_TIMEOUT);
1285
1286 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1287}
1288
1289static void do_input(struct work_struct *work)
1290{
1291 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input);
1292 unsigned long flags;
1293
1294 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1295
1296
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);
1301 i2Input( pCh );
1302 } else
1303 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1304 } else {
1305 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1306
1307 i2InputFlush( pCh );
1308 }
1309}
1310
1311
1312static inline void isig(int sig, struct tty_struct *tty, int flush)
1313{
1314
1315 if (tty->pgrp)
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 );
1321 }
1322}
1323
1324static void do_status(struct work_struct *work)
1325{
1326 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status);
1327 int status;
1328
1329 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1330
1331 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1332
1333 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1334 if ( (status & I2_BRK) ) {
1335
1336 if (I_IGNBRK(pCh->pTTY))
1337 goto skip_this;
1338 if (I_BRKINT(pCh->pTTY)) {
1339 isig(SIGINT, pCh->pTTY, 1);
1340 goto skip_this;
1341 }
1342 wake_up_interruptible(&pCh->pTTY->read_wait);
1343 }
1344#ifdef NEVER_HAPPENS_AS_SETUP_XXX
1345
1346
1347
1348 {
1349 char brkf = TTY_NORMAL;
1350 unsigned char brkc = '\0';
1351 unsigned char tmp;
1352 if ( (status & I2_BRK) ) {
1353 brkf = TTY_BREAK;
1354 brkc = '\0';
1355 }
1356 else if (status & I2_PAR) {
1357 brkf = TTY_PARITY;
1358 brkc = the_char;
1359 } else if (status & I2_FRA) {
1360 brkf = TTY_FRAME;
1361 brkc = the_char;
1362 } else if (status & I2_OVR) {
1363 brkf = TTY_OVERRUN;
1364 brkc = the_char;
1365 }
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;
1370 }
1371#endif
1372 }
1373skip_this:
1374
1375 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1376 wake_up_interruptible(&pCh->delta_msr_wait);
1377
1378 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1379 if ( status & I2_DCD ) {
1380 if ( pCh->wopen ) {
1381 wake_up_interruptible ( &pCh->open_wait );
1382 }
1383 } else {
1384 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1385 tty_hangup( pCh->pTTY );
1386 }
1387 }
1388 }
1389 }
1390
1391 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1392}
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407#ifdef IP2DEBUG_OPEN
1408static void
1409open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1410{
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",
1415 pCh->pMyBord );
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) {
1419 } else {
1420 printk(KERN_INFO "IP2: all pointers check out!\n" );
1421 }
1422}
1423#endif
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438static int
1439ip2_open( PTTY tty, struct file *pFile )
1440{
1441 wait_queue_t wait;
1442 int rc = 0;
1443 int do_clocal = 0;
1444 i2ChanStrPtr pCh = DevTable[tty->index];
1445
1446 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1447
1448 if ( pCh == NULL ) {
1449 return -ENODEV;
1450 }
1451
1452 pCh->pTTY = tty;
1453 tty->driver_data = pCh;
1454
1455#ifdef IP2DEBUG_OPEN
1456 printk(KERN_DEBUG \
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 );
1460#endif
1461
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 );
1465
1466
1467
1468
1469
1470
1471 init_waitqueue_entry(&wait, current);
1472 add_wait_queue(&pCh->close_wait, &wait);
1473 set_current_state( TASK_INTERRUPTIBLE );
1474
1475 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1476 if ( pCh->flags & ASYNC_CLOSING ) {
1477 schedule();
1478 }
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;
1483 }
1484 }
1485 set_current_state( TASK_RUNNING );
1486 remove_wait_queue(&pCh->close_wait, &wait);
1487
1488
1489
1490
1491 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1492 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1493 goto noblock;
1494 }
1495
1496
1497
1498
1499 if ( tty->termios->c_cflag & CLOCAL )
1500 do_clocal = 1;
1501
1502#ifdef IP2DEBUG_OPEN
1503 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1504#endif
1505
1506 ++pCh->wopen;
1507
1508 init_waitqueue_entry(&wait, current);
1509 add_wait_queue(&pCh->open_wait, &wait);
1510
1511 for(;;) {
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;
1520 }
1521 if (!(pCh->flags & ASYNC_CLOSING) &&
1522 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1523 rc = 0;
1524 break;
1525 }
1526
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");
1531#endif
1532 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1533 (pCh->flags & ASYNC_CLOSING) );
1534
1535 if (signal_pending(current)) {
1536 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1537 break;
1538 }
1539 schedule();
1540 }
1541 set_current_state( TASK_RUNNING );
1542 remove_wait_queue(&pCh->open_wait, &wait);
1543
1544 --pCh->wopen;
1545
1546 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1547
1548 if (rc != 0 ) {
1549 return rc;
1550 }
1551 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1552
1553noblock:
1554
1555
1556 if ( tty->count == 1 ) {
1557 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1558
1559 set_params( pCh, NULL );
1560 }
1561
1562
1563
1564
1565
1566 pCh->channelOptions |= CO_NBLOCK_WRITE;
1567
1568#ifdef IP2DEBUG_OPEN
1569 printk (KERN_DEBUG "IP2: open completed\n" );
1570#endif
1571 serviceOutgoingFifo( pCh->pMyBord );
1572
1573 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1574
1575 return 0;
1576}
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588static void
1589ip2_close( PTTY tty, struct file *pFile )
1590{
1591 i2ChanStrPtr pCh = tty->driver_data;
1592
1593 if ( !pCh ) {
1594 return;
1595 }
1596
1597 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1598
1599#ifdef IP2DEBUG_OPEN
1600 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1601#endif
1602
1603 if ( tty_hung_up_p ( pFile ) ) {
1604
1605 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1606
1607 return;
1608 }
1609 if ( tty->count > 1 ) {
1610
1611 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1612
1613 return;
1614 }
1615 pCh->flags |= ASYNC_CLOSING;
1616
1617 tty->closing = 1;
1618
1619 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1620
1621
1622
1623
1624
1625 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1626 }
1627
1628
1629
1630
1631
1632 i2InputFlush( pCh );
1633
1634
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));
1641 }
1642
1643 serviceOutgoingFifo ( pCh->pMyBord );
1644
1645 tty_ldisc_flush(tty);
1646 tty_driver_flush_buffer(tty);
1647 tty->closing = 0;
1648
1649 pCh->pTTY = NULL;
1650
1651 if (pCh->wopen) {
1652 if (pCh->ClosingDelay) {
1653 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1654 }
1655 wake_up_interruptible(&pCh->open_wait);
1656 }
1657
1658 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1659 wake_up_interruptible(&pCh->close_wait);
1660
1661#ifdef IP2DEBUG_OPEN
1662 DBG_CNT("ip2_close: after wakeups--");
1663#endif
1664
1665
1666 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1667
1668 return;
1669}
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680static void
1681ip2_hangup ( PTTY tty )
1682{
1683 i2ChanStrPtr pCh = tty->driver_data;
1684
1685 if( !pCh ) {
1686 return;
1687 }
1688
1689 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1690
1691 ip2_flush_buffer(tty);
1692
1693
1694
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));
1701 }
1702 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1703 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1704 serviceOutgoingFifo ( pCh->pMyBord );
1705
1706 wake_up_interruptible ( &pCh->delta_msr_wait );
1707
1708 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1709 pCh->pTTY = NULL;
1710 wake_up_interruptible ( &pCh->open_wait );
1711
1712 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1713}
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733static int
1734ip2_write( PTTY tty, const unsigned char *pData, int count)
1735{
1736 i2ChanStrPtr pCh = tty->driver_data;
1737 int bytesSent = 0;
1738 unsigned long flags;
1739
1740 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1741
1742
1743 ip2_flush_chars( tty );
1744
1745
1746 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1747 bytesSent = i2Output( pCh, pData, count);
1748 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1749
1750 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1751
1752 return bytesSent > 0 ? bytesSent : 0;
1753}
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765static int
1766ip2_putchar( PTTY tty, unsigned char ch )
1767{
1768 i2ChanStrPtr pCh = tty->driver_data;
1769 unsigned long flags;
1770
1771
1772
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 );
1778 } else
1779 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1780 return 1;
1781
1782
1783}
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793static void
1794ip2_flush_chars( PTTY tty )
1795{
1796 int strip;
1797 i2ChanStrPtr pCh = tty->driver_data;
1798 unsigned long flags;
1799
1800 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1801 if ( pCh->Pbuf_stuff ) {
1802
1803
1804
1805
1806
1807
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 );
1811 }
1812 pCh->Pbuf_stuff -= strip;
1813 }
1814 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1815}
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825static int
1826ip2_write_room ( PTTY tty )
1827{
1828 int bytesFree;
1829 i2ChanStrPtr pCh = tty->driver_data;
1830 unsigned long flags;
1831
1832 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1833 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1834 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1835
1836 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1837
1838 return ((bytesFree > 0) ? bytesFree : 0);
1839}
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850static int
1851ip2_chars_in_buf ( PTTY tty )
1852{
1853 i2ChanStrPtr pCh = tty->driver_data;
1854 int rc;
1855 unsigned long flags;
1856
1857 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1858
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 );
1863#endif
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);
1870 return rc;
1871}
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882static void
1883ip2_flush_buffer( PTTY tty )
1884{
1885 i2ChanStrPtr pCh = tty->driver_data;
1886 unsigned long flags;
1887
1888 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1889
1890#ifdef IP2DEBUG_WRITE
1891 printk (KERN_DEBUG "IP2: flush buffer\n" );
1892#endif
1893 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1894 pCh->Pbuf_stuff = 0;
1895 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1896 i2FlushOutput( pCh );
1897 ip2_owake(tty);
1898
1899 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1900
1901}
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915static void
1916ip2_wait_until_sent ( PTTY tty, int timeout )
1917{
1918 int i = jiffies;
1919 i2ChanStrPtr pCh = tty->driver_data;
1920
1921 tty_wait_until_sent(tty, timeout );
1922 if ( (i = timeout - (jiffies -i)) > 0)
1923 i2DrainOutput( pCh, i );
1924}
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941static void
1942ip2_throttle ( PTTY tty )
1943{
1944 i2ChanStrPtr pCh = tty->driver_data;
1945
1946#ifdef IP2DEBUG_READ
1947 printk (KERN_DEBUG "IP2: throttle\n" );
1948#endif
1949
1950
1951
1952
1953
1954
1955 pCh->throttled = 1;
1956}
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967static void
1968ip2_unthrottle ( PTTY tty )
1969{
1970 i2ChanStrPtr pCh = tty->driver_data;
1971 unsigned long flags;
1972
1973#ifdef IP2DEBUG_READ
1974 printk (KERN_DEBUG "IP2: unthrottle\n" );
1975#endif
1976
1977
1978 pCh->throttled = 0;
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" );
1986#endif
1987 i2Input( pCh );
1988 } else
1989 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1990}
1991
1992static void
1993ip2_start ( PTTY tty )
1994{
1995 i2ChanStrPtr pCh = DevTable[tty->index];
1996
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" );
2002#endif
2003}
2004
2005static void
2006ip2_stop ( PTTY tty )
2007{
2008 i2ChanStrPtr pCh = DevTable[tty->index];
2009
2010 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
2011#ifdef IP2DEBUG_WRITE
2012 printk (KERN_DEBUG "IP2: stop tx\n" );
2013#endif
2014}
2015
2016
2017
2018
2019
2020static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2021{
2022 i2ChanStrPtr pCh = DevTable[tty->index];
2023#ifdef ENABLE_DSSNOW
2024 wait_queue_t wait;
2025#endif
2026
2027 if (pCh == NULL)
2028 return -ENODEV;
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041#ifdef ENABLE_DSSNOW
2042 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2043
2044 init_waitqueue_entry(&wait, current);
2045 add_wait_queue(&pCh->dss_now_wait, &wait);
2046 set_current_state( TASK_INTERRUPTIBLE );
2047
2048 serviceOutgoingFifo( pCh->pMyBord );
2049
2050 schedule();
2051
2052 set_current_state( TASK_RUNNING );
2053 remove_wait_queue(&pCh->dss_now_wait, &wait);
2054
2055 if (signal_pending(current)) {
2056 return -EINTR;
2057 }
2058#endif
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);
2065}
2066
2067static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2068 unsigned int set, unsigned int clear)
2069{
2070 i2ChanStrPtr pCh = DevTable[tty->index];
2071
2072 if (pCh == NULL)
2073 return -ENODEV;
2074
2075 if (set & TIOCM_RTS) {
2076 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2077 pCh->dataSetOut |= I2_RTS;
2078 }
2079 if (set & TIOCM_DTR) {
2080 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2081 pCh->dataSetOut |= I2_DTR;
2082 }
2083
2084 if (clear & TIOCM_RTS) {
2085 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2086 pCh->dataSetOut &= ~I2_RTS;
2087 }
2088 if (clear & TIOCM_DTR) {
2089 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2090 pCh->dataSetOut &= ~I2_DTR;
2091 }
2092 serviceOutgoingFifo( pCh->pMyBord );
2093 return 0;
2094}
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108static int
2109ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2110{
2111 wait_queue_t wait;
2112 i2ChanStrPtr pCh = DevTable[tty->index];
2113 i2eBordStrPtr pB;
2114 struct async_icount cprev, cnow;
2115 struct serial_icounter_struct __user *p_cuser;
2116 int rc = 0;
2117 unsigned long flags;
2118 void __user *argp = (void __user *)arg;
2119
2120 if ( pCh == NULL )
2121 return -ENODEV;
2122
2123 pB = pCh->pMyBord;
2124
2125 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2126
2127#ifdef IP2DEBUG_IOCTL
2128 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2129#endif
2130
2131 switch(cmd) {
2132 case TIOCGSERIAL:
2133
2134 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2135
2136 rc = get_serial_info(pCh, argp);
2137 if (rc)
2138 return rc;
2139 break;
2140
2141 case TIOCSSERIAL:
2142
2143 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2144
2145 rc = set_serial_info(pCh, argp);
2146 if (rc)
2147 return rc;
2148 break;
2149
2150 case TCXONC:
2151 rc = tty_check_change(tty);
2152 if (rc)
2153 return rc;
2154 switch (arg) {
2155 case TCOOFF:
2156
2157 break;
2158 case TCOON:
2159
2160 break;
2161 case TCIOFF:
2162 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2163 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2164 CMD_XMIT_NOW(STOP_CHAR(tty)));
2165 }
2166 break;
2167 case TCION:
2168 if (START_CHAR(tty) != __DISABLED_CHAR) {
2169 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2170 CMD_XMIT_NOW(START_CHAR(tty)));
2171 }
2172 break;
2173 default:
2174 return -EINVAL;
2175 }
2176 return 0;
2177
2178 case TCSBRK:
2179 rc = tty_check_change(tty);
2180
2181 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2182
2183 if (!rc) {
2184 ip2_wait_until_sent(tty,0);
2185 if (!arg) {
2186 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2187 serviceOutgoingFifo( pCh->pMyBord );
2188 }
2189 }
2190 break;
2191
2192 case TCSBRKP:
2193 rc = tty_check_change(tty);
2194
2195 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2196
2197 if (!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 );
2202 }
2203 break;
2204
2205 case TIOCGSOFTCAR:
2206
2207 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2208
2209 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2210 if (rc)
2211 return rc;
2212 break;
2213
2214 case TIOCSSOFTCAR:
2215
2216 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2217
2218 rc = get_user(arg,(unsigned long __user *) argp);
2219 if (rc)
2220 return rc;
2221 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2222 | (arg ? CLOCAL : 0));
2223
2224 break;
2225
2226
2227
2228
2229
2230
2231 case TIOCMIWAIT:
2232 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2233 cprev = pCh->icount;
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 );
2240
2241 serviceOutgoingFifo( pCh->pMyBord );
2242 for(;;) {
2243 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2244
2245 schedule();
2246
2247 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2248
2249
2250 if (signal_pending(current)) {
2251 rc = -ERESTARTSYS;
2252 break;
2253 }
2254 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2255 cnow = pCh->icount;
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;
2260 break;
2261 }
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)) ) {
2266 rc = 0;
2267 break;
2268 }
2269 cprev = cnow;
2270 }
2271 set_current_state( TASK_RUNNING );
2272 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2273
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);
2278 }
2279 serviceOutgoingFifo( pCh->pMyBord );
2280 return rc;
2281 break;
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291 case TIOCGICOUNT:
2292 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2293
2294 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2295 cnow = pCh->icount;
2296 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2297 p_cuser = argp;
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);
2309 break;
2310
2311
2312
2313
2314
2315 case TIOCSERCONFIG:
2316 case TIOCSERGWILD:
2317 case TIOCSERGETLSR:
2318 case TIOCSERSWILD:
2319 case TIOCSERGSTRUCT:
2320 case TIOCSERGETMULTI:
2321 case TIOCSERSETMULTI:
2322
2323 default:
2324 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2325
2326 rc = -ENOIOCTLCMD;
2327 break;
2328 }
2329
2330 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2331
2332 return rc;
2333}
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345static int
2346get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2347{
2348 struct serial_struct tmp;
2349
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;
2354 } else {
2355 tmp.type = PORT_CIRRUS;
2356 }
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));
2366}
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379static int
2380set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2381{
2382 struct serial_struct ns;
2383 int old_flags, old_baud_divisor;
2384
2385 if (copy_from_user(&ns, new_info, sizeof (ns)))
2386 return -EFAULT;
2387
2388
2389
2390
2391
2392
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) ) {
2397 return -EINVAL;
2398 }
2399
2400 old_flags = pCh->flags;
2401 old_baud_divisor = pCh->BaudDivisor;
2402
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) ) ) {
2407 return -EPERM;
2408 }
2409
2410 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2411 (ns.flags & ASYNC_USR_MASK);
2412 pCh->BaudDivisor = ns.custom_divisor;
2413 } else {
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;
2419 }
2420
2421 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2422 || (old_baud_divisor != pCh->BaudDivisor) ) {
2423
2424 set_params( pCh, NULL );
2425 }
2426
2427 return 0;
2428}
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440static void
2441ip2_set_termios( PTTY tty, struct ktermios *old_termios )
2442{
2443 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2444
2445#ifdef IP2DEBUG_IOCTL
2446 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2447#endif
2448
2449 set_params( pCh, old_termios );
2450}
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461static void
2462ip2_set_line_discipline ( PTTY tty )
2463{
2464#ifdef IP2DEBUG_IOCTL
2465 printk (KERN_DEBUG "IP2: set line discipline\n" );
2466#endif
2467
2468 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2469
2470}
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482static void
2483set_params( i2ChanStrPtr pCh, struct ktermios *o_tios )
2484{
2485 tcflag_t cflag, iflag, lflag;
2486 char stop_char, start_char;
2487 struct ktermios dummy;
2488
2489 lflag = pCh->pTTY->termios->c_lflag;
2490 cflag = pCh->pTTY->termios->c_cflag;
2491 iflag = pCh->pTTY->termios->c_iflag;
2492
2493 if (o_tios == NULL) {
2494 dummy.c_lflag = ~lflag;
2495 dummy.c_cflag = ~cflag;
2496 dummy.c_iflag = ~iflag;
2497 o_tios = &dummy;
2498 }
2499
2500 {
2501 switch ( cflag & CBAUD ) {
2502 case B0:
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);
2507 goto service_it;
2508 break;
2509 case B38400:
2510
2511
2512
2513
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;
2520 } else {
2521 pCh->speed = CBR_38400;
2522 }
2523 break;
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;
2546 }
2547 if ( pCh->speed == CBR_C1 ) {
2548
2549 int bps = pCh->BaudBase / pCh->BaudDivisor;
2550 if ( bps == 921600 ) {
2551 pCh->speed = CBR_921600;
2552 } else {
2553 bps = bps/10;
2554 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2555 }
2556 }
2557 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2558
2559 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2560 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2561 }
2562 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2563 {
2564 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2565 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2566 }
2567 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2568 {
2569 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2570 CMD_SETPAR(
2571 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2572 )
2573 );
2574 }
2575
2576 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2577 {
2578 int datasize;
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;
2585 }
2586 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2587 }
2588
2589 if ( (cflag & CRTSCTS) ) {
2590 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2591 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2592 } else {
2593 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2594 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2595 }
2596
2597
2598
2599 stop_char = STOP_CHAR(pCh->pTTY);
2600 start_char = START_CHAR(pCh->pTTY);
2601
2602
2603 if (stop_char == __DISABLED_CHAR )
2604 {
2605 stop_char = ~__DISABLED_CHAR;
2606 }
2607 if (start_char == __DISABLED_CHAR )
2608 {
2609 start_char = ~__DISABLED_CHAR;
2610 }
2611
2612
2613 if ( o_tios->c_cc[VSTART] != start_char )
2614 {
2615 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2616 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2617 }
2618 if ( o_tios->c_cc[VSTOP] != stop_char )
2619 {
2620 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2621 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2622 }
2623 if (stop_char == __DISABLED_CHAR )
2624 {
2625 stop_char = ~__DISABLED_CHAR;
2626 goto no_xoff;
2627 }
2628 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2629 {
2630 if ( iflag & IXOFF ) {
2631 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2632 } else {
2633no_xoff:
2634 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2635 }
2636 }
2637 if (start_char == __DISABLED_CHAR )
2638 {
2639 goto no_xon;
2640 }
2641 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2642 {
2643 if ( iflag & IXON ) {
2644 if ( iflag & IXANY ) {
2645 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2646 } else {
2647 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2648 }
2649 } else {
2650no_xon:
2651 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2652 }
2653 }
2654 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2655 {
2656 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2657 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2658 }
2659 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2660 {
2661 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2662 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2663 }
2664
2665 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2666 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2667 {
2668 char brkrpt = 0;
2669 char parrpt = 0;
2670
2671 if ( iflag & IGNBRK ) {
2672
2673 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2674 } else {
2675 if ( iflag & BRKINT ) {
2676 if ( iflag & PARMRK ) {
2677 brkrpt = 0x0a;
2678 } else {
2679 brkrpt = 0x1a;
2680 }
2681 brkrpt |= 0x04;
2682 } else {
2683 if ( iflag & PARMRK ) {
2684 brkrpt = 0x0b;
2685 } else {
2686 brkrpt = 0x01;
2687 }
2688 }
2689 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2690 }
2691
2692 if (iflag & IGNPAR) {
2693 parrpt = 0x20;
2694
2695
2696 } else {
2697 if ( iflag & PARMRK ) {
2698
2699
2700
2701 parrpt = 0x04 ;
2702 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2703 } else {
2704 parrpt = 0x03;
2705 }
2706 }
2707 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2708 }
2709 if (cflag & CLOCAL) {
2710
2711 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2712 pCh->flags &= ~ASYNC_CHECK_CD;
2713 } else {
2714 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2715 pCh->flags |= ASYNC_CHECK_CD;
2716 }
2717
2718service_it:
2719 i2DrainOutput( pCh, 100 );
2720}
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739static
2740ssize_t
2741ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2742{
2743 unsigned int minor = iminor(pFile->f_path.dentry->d_inode);
2744 int rc = 0;
2745
2746#ifdef IP2DEBUG_IPL
2747 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2748#endif
2749
2750 switch( minor ) {
2751 case 0:
2752 rc = -EINVAL;
2753 break;
2754 case 1:
2755 rc = -EINVAL;
2756 break;
2757 case 2:
2758 rc = -EINVAL;
2759 break;
2760 case 3:
2761 rc = DumpTraceBuffer ( pData, count );
2762 break;
2763 case 4:
2764 rc = DumpFifoBuffer ( pData, count );
2765 break;
2766 default:
2767 rc = -ENODEV;
2768 break;
2769 }
2770 return rc;
2771}
2772
2773static int
2774DumpFifoBuffer ( char __user *pData, int count )
2775{
2776#ifdef DEBUG_FIFO
2777 int rc;
2778 rc = copy_to_user(pData, DBGBuf, count);
2779
2780 printk(KERN_DEBUG "Last index %d\n", I );
2781
2782 return count;
2783#endif
2784 return 0;
2785}
2786
2787static int
2788DumpTraceBuffer ( char __user *pData, int count )
2789{
2790#ifdef IP2DEBUG_TRACE
2791 int rc;
2792 int dumpcount;
2793 int chunk;
2794 int *pIndex = (int __user *)pData;
2795
2796 if ( count < (sizeof(int) * 6) ) {
2797 return -EIO;
2798 }
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;
2805
2806 dumpcount = tracestuff - tracestrip;
2807 if ( dumpcount < 0 ) {
2808 dumpcount += TRACEMAX;
2809 }
2810 if ( dumpcount > count ) {
2811 dumpcount = count;
2812 }
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]);
2818 tracestrip = 0;
2819 chunk = dumpcount - chunk;
2820 } else {
2821 chunk = dumpcount;
2822 }
2823 rc = copy_to_user(pData, &tracebuf[tracestrip],
2824 chunk * sizeof(tracebuf[0]) );
2825 tracestrip += chunk;
2826 tracewrap = 0;
2827
2828 rc = put_user(tracestrip, ++pIndex );
2829 rc = put_user(tracestuff, ++pIndex );
2830
2831 return dumpcount;
2832#else
2833 return 0;
2834#endif
2835}
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849static ssize_t
2850ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2851{
2852#ifdef IP2DEBUG_IPL
2853 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2854#endif
2855 return 0;
2856}
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870static long
2871ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
2872{
2873 unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode);
2874 int rc = 0;
2875 void __user *argp = (void __user *)arg;
2876 ULONG __user *pIndex = argp;
2877 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2878 i2ChanStrPtr pCh;
2879
2880#ifdef IP2DEBUG_IPL
2881 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2882#endif
2883
2884 lock_kernel();
2885
2886 switch ( iplminor ) {
2887 case 0:
2888 rc = -EINVAL;
2889 break;
2890 case 1:
2891 case 5:
2892 case 9:
2893 case 13:
2894 switch ( cmd ) {
2895 case 64:
2896 rc = put_user(-1, pIndex++ );
2897 rc = put_user(irq_counter, pIndex++ );
2898 rc = put_user(bh_counter, pIndex++ );
2899 break;
2900
2901 case 65:
2902 if ( pB ) {
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 ) );
2906 } else {
2907 rc = -ENODEV;
2908 }
2909 break;
2910
2911 default:
2912 if (cmd < IP2_MAX_PORTS) {
2913 pCh = DevTable[cmd];
2914 if ( pCh )
2915 {
2916 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2917 } else {
2918 rc = -ENODEV;
2919 }
2920 } else {
2921 rc = -EINVAL;
2922 }
2923 }
2924 break;
2925
2926 case 2:
2927 rc = -EINVAL;
2928 break;
2929 case 3:
2930
2931
2932
2933
2934
2935
2936 if (cmd == 1)
2937 rc = 0;
2938 else
2939 rc = -EINVAL;
2940 break;
2941
2942 default:
2943 rc = -ENODEV;
2944 break;
2945 }
2946 unlock_kernel();
2947 return rc;
2948}
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960static int
2961ip2_ipl_open( struct inode *pInode, struct file *pFile )
2962{
2963
2964#ifdef IP2DEBUG_IPL
2965 printk (KERN_DEBUG "IP2IPL: open\n" );
2966#endif
2967 cycle_kernel_lock();
2968 return 0;
2969}
2970
2971static int
2972proc_ip2mem_show(struct seq_file *m, void *v)
2973{
2974 i2eBordStrPtr pB;
2975 i2ChanStrPtr pCh;
2976 PTTY tty;
2977 int i;
2978
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"
2982
2983 seq_printf(m,"\n");
2984
2985 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
2986 pB = i2BoardPtrTable[i];
2987 if ( pB ) {
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);
2991 }
2992 }
2993
2994 seq_printf(m,"#: tty flags, port flags, cflags, iflags\n");
2995 for (i=0; i < IP2_MAX_PORTS; i++) {
2996 pCh = DevTable[i];
2997 if (pCh) {
2998 tty = pCh->pTTY;
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);
3002
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);
3006 }
3007 }
3008 }
3009 return 0;
3010}
3011
3012static int proc_ip2mem_open(struct inode *inode, struct file *file)
3013{
3014 return single_open(file, proc_ip2mem_show, NULL);
3015}
3016
3017static const struct file_operations ip2mem_proc_fops = {
3018 .owner = THIS_MODULE,
3019 .open = proc_ip2mem_open,
3020 .read = seq_read,
3021 .llseek = seq_lseek,
3022 .release = single_release,
3023};
3024
3025
3026
3027
3028
3029
3030
3031
3032static int ip2_proc_show(struct seq_file *m, void *v)
3033{
3034 int i, j, box;
3035 int boxes = 0;
3036 int ports = 0;
3037 int tports = 0;
3038 i2eBordStrPtr pB;
3039 char *sep;
3040
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);
3045
3046 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3047
3048 boxes = 0;
3049 pB = i2BoardPtrTable[i];
3050 if( pB ) {
3051 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3052 {
3053 case POR_ID_FIIEX:
3054 seq_printf(m, "Board %d: EX ports=", i);
3055 sep = "";
3056 for( box = 0; box < ABS_MAX_BOXES; ++box )
3057 {
3058 ports = 0;
3059
3060 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3061 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3062 {
3063 if( pB->i2eChannelMap[box] & 1<< j ) {
3064 ++ports;
3065 }
3066 }
3067 seq_printf(m, "%s%d", sep, ports);
3068 sep = ",";
3069 tports += ports;
3070 }
3071 seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
3072 break;
3073
3074 case POR_ID_II_4:
3075 seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
3076 tports = ports = 4;
3077 break;
3078
3079 case POR_ID_II_8:
3080 seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
3081 tports = ports = 8;
3082 break;
3083
3084 case POR_ID_II_8R:
3085 seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
3086 tports = ports = 8;
3087 break;
3088
3089 default:
3090 seq_printf(m, "Board %d: unknown", i);
3091
3092 tports = ports = 0;
3093 }
3094
3095 } else {
3096
3097 seq_printf(m, "Board %d: vacant", i);
3098 tports = ports = 0;
3099 }
3100
3101 if( tports ) {
3102 seq_puts(m, " minors=");
3103 sep = "";
3104 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3105 {
3106 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3107 {
3108 if ( pB->i2eChannelMap[box] & (1 << j) )
3109 {
3110 seq_printf(m, "%s%d", sep,
3111 j + ABS_BIGGEST_BOX *
3112 (box+i*ABS_MAX_BOXES));
3113 sep = ",";
3114 }
3115 }
3116 }
3117 }
3118 seq_putc(m, '\n');
3119 }
3120 return 0;
3121 }
3122
3123static int ip2_proc_open(struct inode *inode, struct file *file)
3124{
3125 return single_open(file, ip2_proc_show, NULL);
3126}
3127
3128static const struct file_operations ip2_proc_fops = {
3129 .owner = THIS_MODULE,
3130 .open = ip2_proc_open,
3131 .read = seq_read,
3132 .llseek = seq_lseek,
3133 .release = single_release,
3134};
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145#ifdef IP2DEBUG_TRACE
3146void
3147ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3148{
3149 long flags;
3150 unsigned long *pCode = &codes;
3151 union ip2breadcrumb bc;
3152 i2ChanStrPtr pCh;
3153
3154
3155 tracebuf[tracestuff++] = jiffies;
3156 if ( tracestuff == TRACEMAX ) {
3157 tracestuff = 0;
3158 }
3159 if ( tracestuff == tracestrip ) {
3160 if ( ++tracestrip == TRACEMAX ) {
3161 tracestrip = 0;
3162 }
3163 ++tracewrap;
3164 }
3165
3166 bc.hdr.port = 0xff & pn;
3167 bc.hdr.cat = cat;
3168 bc.hdr.codes = (unsigned char)( codes & 0xff );
3169 bc.hdr.label = label;
3170 tracebuf[tracestuff++] = bc.value;
3171
3172 for (;;) {
3173 if ( tracestuff == TRACEMAX ) {
3174 tracestuff = 0;
3175 }
3176 if ( tracestuff == tracestrip ) {
3177 if ( ++tracestrip == TRACEMAX ) {
3178 tracestrip = 0;
3179 }
3180 ++tracewrap;
3181 }
3182
3183 if ( !codes-- )
3184 break;
3185
3186 tracebuf[tracestuff++] = *++pCode;
3187 }
3188}
3189#endif
3190
3191
3192MODULE_LICENSE("GPL");
3193
3194static struct pci_device_id ip2main_pci_tbl[] __devinitdata = {
3195 { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) },
3196 { }
3197};
3198
3199MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);
3200