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#include <linux/module.h>
30#include <linux/kernel.h>
31#include <linux/types.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34#include <linux/serial.h>
35#include <linux/delay.h>
36#include <linux/ctype.h>
37#include <linux/tty.h>
38#include <linux/tty_flip.h>
39#include <linux/slab.h>
40#include <linux/smp_lock.h>
41#include <linux/ioport.h>
42#include <linux/interrupt.h>
43#include <linux/uaccess.h>
44#include <linux/io.h>
45#include <linux/spinlock.h>
46#include <linux/pci.h>
47#include "digiPCI.h"
48
49
50#include "digi1.h"
51#include "digiFep1.h"
52#include "epca.h"
53#include "epcaconfig.h"
54
55#define VERSION "1.3.0.1-LK2.6"
56
57
58#define DIGIINFOMAJOR 35
59
60
61#define MAXCARDS 7
62#define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg)
63
64#define PFX "epca: "
65
66static int nbdevs, num_cards, liloconfig;
67static int digi_poller_inhibited = 1 ;
68
69static int setup_error_code;
70static int invalid_lilo_config;
71
72
73
74
75
76
77
78static DEFINE_SPINLOCK(epca_lock);
79
80
81
82static struct board_info boards[MAXBOARDS];
83
84static struct tty_driver *pc_driver;
85static struct tty_driver *pc_info;
86
87
88
89
90
91
92
93
94
95
96static struct channel digi_channels[MAX_ALLOC];
97
98
99
100
101
102
103static struct channel *card_ptr[MAXCARDS];
104
105static struct timer_list epca_timer;
106
107
108
109
110
111static void memwinon(struct board_info *b, unsigned int win);
112static void memwinoff(struct board_info *b, unsigned int win);
113static void globalwinon(struct channel *ch);
114static void rxwinon(struct channel *ch);
115static void txwinon(struct channel *ch);
116static void memoff(struct channel *ch);
117static void assertgwinon(struct channel *ch);
118static void assertmemoff(struct channel *ch);
119
120
121
122static void pcxem_memwinon(struct board_info *b, unsigned int win);
123static void pcxem_memwinoff(struct board_info *b, unsigned int win);
124static void pcxem_globalwinon(struct channel *ch);
125static void pcxem_rxwinon(struct channel *ch);
126static void pcxem_txwinon(struct channel *ch);
127static void pcxem_memoff(struct channel *ch);
128
129
130
131static void pcxe_memwinon(struct board_info *b, unsigned int win);
132static void pcxe_memwinoff(struct board_info *b, unsigned int win);
133static void pcxe_globalwinon(struct channel *ch);
134static void pcxe_rxwinon(struct channel *ch);
135static void pcxe_txwinon(struct channel *ch);
136static void pcxe_memoff(struct channel *ch);
137
138
139
140
141static void pcxi_memwinon(struct board_info *b, unsigned int win);
142static void pcxi_memwinoff(struct board_info *b, unsigned int win);
143static void pcxi_globalwinon(struct channel *ch);
144static void pcxi_rxwinon(struct channel *ch);
145static void pcxi_txwinon(struct channel *ch);
146static void pcxi_memoff(struct channel *ch);
147
148
149
150static void dummy_memwinon(struct board_info *b, unsigned int win);
151static void dummy_memwinoff(struct board_info *b, unsigned int win);
152static void dummy_globalwinon(struct channel *ch);
153static void dummy_rxwinon(struct channel *ch);
154static void dummy_txwinon(struct channel *ch);
155static void dummy_memoff(struct channel *ch);
156static void dummy_assertgwinon(struct channel *ch);
157static void dummy_assertmemoff(struct channel *ch);
158
159static struct channel *verifyChannel(struct tty_struct *);
160static void pc_sched_event(struct channel *, int);
161static void epca_error(int, char *);
162static void pc_close(struct tty_struct *, struct file *);
163static void shutdown(struct channel *, struct tty_struct *tty);
164static void pc_hangup(struct tty_struct *);
165static int pc_write_room(struct tty_struct *);
166static int pc_chars_in_buffer(struct tty_struct *);
167static void pc_flush_buffer(struct tty_struct *);
168static void pc_flush_chars(struct tty_struct *);
169static int pc_open(struct tty_struct *, struct file *);
170static void post_fep_init(unsigned int crd);
171static void epcapoll(unsigned long);
172static void doevent(int);
173static void fepcmd(struct channel *, int, int, int, int, int);
174static unsigned termios2digi_h(struct channel *ch, unsigned);
175static unsigned termios2digi_i(struct channel *ch, unsigned);
176static unsigned termios2digi_c(struct channel *ch, unsigned);
177static void epcaparam(struct tty_struct *, struct channel *);
178static void receive_data(struct channel *, struct tty_struct *tty);
179static int pc_ioctl(struct tty_struct *, struct file *,
180 unsigned int, unsigned long);
181static int info_ioctl(struct tty_struct *, struct file *,
182 unsigned int, unsigned long);
183static void pc_set_termios(struct tty_struct *, struct ktermios *);
184static void do_softint(struct work_struct *work);
185static void pc_stop(struct tty_struct *);
186static void pc_start(struct tty_struct *);
187static void pc_throttle(struct tty_struct *tty);
188static void pc_unthrottle(struct tty_struct *tty);
189static int pc_send_break(struct tty_struct *tty, int msec);
190static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
191
192static int pc_write(struct tty_struct *, const unsigned char *, int);
193static int pc_init(void);
194static int init_PCI(void);
195
196
197
198
199
200
201
202
203
204
205static void memwinon(struct board_info *b, unsigned int win)
206{
207 b->memwinon(b, win);
208}
209
210static void memwinoff(struct board_info *b, unsigned int win)
211{
212 b->memwinoff(b, win);
213}
214
215static void globalwinon(struct channel *ch)
216{
217 ch->board->globalwinon(ch);
218}
219
220static void rxwinon(struct channel *ch)
221{
222 ch->board->rxwinon(ch);
223}
224
225static void txwinon(struct channel *ch)
226{
227 ch->board->txwinon(ch);
228}
229
230static void memoff(struct channel *ch)
231{
232 ch->board->memoff(ch);
233}
234static void assertgwinon(struct channel *ch)
235{
236 ch->board->assertgwinon(ch);
237}
238
239static void assertmemoff(struct channel *ch)
240{
241 ch->board->assertmemoff(ch);
242}
243
244
245static void pcxem_memwinon(struct board_info *b, unsigned int win)
246{
247 outb_p(FEPWIN | win, b->port + 1);
248}
249
250static void pcxem_memwinoff(struct board_info *b, unsigned int win)
251{
252 outb_p(0, b->port + 1);
253}
254
255static void pcxem_globalwinon(struct channel *ch)
256{
257 outb_p(FEPWIN, (int)ch->board->port + 1);
258}
259
260static void pcxem_rxwinon(struct channel *ch)
261{
262 outb_p(ch->rxwin, (int)ch->board->port + 1);
263}
264
265static void pcxem_txwinon(struct channel *ch)
266{
267 outb_p(ch->txwin, (int)ch->board->port + 1);
268}
269
270static void pcxem_memoff(struct channel *ch)
271{
272 outb_p(0, (int)ch->board->port + 1);
273}
274
275
276static void pcxe_memwinon(struct board_info *b, unsigned int win)
277{
278 outb_p(FEPWIN | win, b->port + 1);
279}
280
281static void pcxe_memwinoff(struct board_info *b, unsigned int win)
282{
283 outb_p(inb(b->port) & ~FEPMEM, b->port + 1);
284 outb_p(0, b->port + 1);
285}
286
287static void pcxe_globalwinon(struct channel *ch)
288{
289 outb_p(FEPWIN, (int)ch->board->port + 1);
290}
291
292static void pcxe_rxwinon(struct channel *ch)
293{
294 outb_p(ch->rxwin, (int)ch->board->port + 1);
295}
296
297static void pcxe_txwinon(struct channel *ch)
298{
299 outb_p(ch->txwin, (int)ch->board->port + 1);
300}
301
302static void pcxe_memoff(struct channel *ch)
303{
304 outb_p(0, (int)ch->board->port);
305 outb_p(0, (int)ch->board->port + 1);
306}
307
308
309static void pcxi_memwinon(struct board_info *b, unsigned int win)
310{
311 outb_p(inb(b->port) | FEPMEM, b->port);
312}
313
314static void pcxi_memwinoff(struct board_info *b, unsigned int win)
315{
316 outb_p(inb(b->port) & ~FEPMEM, b->port);
317}
318
319static void pcxi_globalwinon(struct channel *ch)
320{
321 outb_p(FEPMEM, ch->board->port);
322}
323
324static void pcxi_rxwinon(struct channel *ch)
325{
326 outb_p(FEPMEM, ch->board->port);
327}
328
329static void pcxi_txwinon(struct channel *ch)
330{
331 outb_p(FEPMEM, ch->board->port);
332}
333
334static void pcxi_memoff(struct channel *ch)
335{
336 outb_p(0, ch->board->port);
337}
338
339static void pcxi_assertgwinon(struct channel *ch)
340{
341 epcaassert(inb(ch->board->port) & FEPMEM, "Global memory off");
342}
343
344static void pcxi_assertmemoff(struct channel *ch)
345{
346 epcaassert(!(inb(ch->board->port) & FEPMEM), "Memory on");
347}
348
349
350
351
352
353
354
355
356static void dummy_memwinon(struct board_info *b, unsigned int win)
357{
358}
359
360static void dummy_memwinoff(struct board_info *b, unsigned int win)
361{
362}
363
364static void dummy_globalwinon(struct channel *ch)
365{
366}
367
368static void dummy_rxwinon(struct channel *ch)
369{
370}
371
372static void dummy_txwinon(struct channel *ch)
373{
374}
375
376static void dummy_memoff(struct channel *ch)
377{
378}
379
380static void dummy_assertgwinon(struct channel *ch)
381{
382}
383
384static void dummy_assertmemoff(struct channel *ch)
385{
386}
387
388static struct channel *verifyChannel(struct tty_struct *tty)
389{
390
391
392
393
394
395
396 if (tty) {
397 struct channel *ch = tty->driver_data;
398 if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) {
399 if (ch->magic == EPCA_MAGIC)
400 return ch;
401 }
402 }
403 return NULL;
404}
405
406static void pc_sched_event(struct channel *ch, int event)
407{
408
409
410
411
412 ch->event |= 1 << event;
413 schedule_work(&ch->tqueue);
414}
415
416static void epca_error(int line, char *msg)
417{
418 printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg);
419}
420
421static void pc_close(struct tty_struct *tty, struct file *filp)
422{
423 struct channel *ch;
424 struct tty_port *port;
425
426
427
428
429 ch = verifyChannel(tty);
430 if (ch == NULL)
431 return;
432 port = &ch->port;
433
434 if (tty_port_close_start(port, tty, filp) == 0)
435 return;
436
437 pc_flush_buffer(tty);
438 shutdown(ch, tty);
439
440 tty_port_close_end(port, tty);
441 ch->event = 0;
442 tty_port_tty_set(port, NULL);
443}
444
445static void shutdown(struct channel *ch, struct tty_struct *tty)
446{
447 unsigned long flags;
448 struct board_chan __iomem *bc;
449 struct tty_port *port = &ch->port;
450
451 if (!(port->flags & ASYNC_INITIALIZED))
452 return;
453
454 spin_lock_irqsave(&epca_lock, flags);
455
456 globalwinon(ch);
457 bc = ch->brdchan;
458
459
460
461
462
463
464 if (bc)
465 writeb(0, &bc->idata);
466
467
468 if (tty->termios->c_cflag & HUPCL) {
469 ch->omodem &= ~(ch->m_rts | ch->m_dtr);
470 fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1);
471 }
472 memoff(ch);
473
474
475
476
477
478
479 port->flags &= ~ASYNC_INITIALIZED;
480 spin_unlock_irqrestore(&epca_lock, flags);
481}
482
483static void pc_hangup(struct tty_struct *tty)
484{
485 struct channel *ch;
486
487
488
489
490
491 ch = verifyChannel(tty);
492 if (ch != NULL) {
493 pc_flush_buffer(tty);
494 tty_ldisc_flush(tty);
495 shutdown(ch, tty);
496
497 ch->event = 0;
498 tty_port_hangup(&ch->port);
499 }
500}
501
502static int pc_write(struct tty_struct *tty,
503 const unsigned char *buf, int bytesAvailable)
504{
505 unsigned int head, tail;
506 int dataLen;
507 int size;
508 int amountCopied;
509 struct channel *ch;
510 unsigned long flags;
511 int remain;
512 struct board_chan __iomem *bc;
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527 ch = verifyChannel(tty);
528 if (ch == NULL)
529 return 0;
530
531
532 bc = ch->brdchan;
533 size = ch->txbufsize;
534 amountCopied = 0;
535
536 spin_lock_irqsave(&epca_lock, flags);
537 globalwinon(ch);
538
539 head = readw(&bc->tin) & (size - 1);
540 tail = readw(&bc->tout);
541
542 if (tail != readw(&bc->tout))
543 tail = readw(&bc->tout);
544 tail &= (size - 1);
545
546 if (head >= tail) {
547
548
549
550
551
552
553
554
555
556 dataLen = size - head;
557 remain = size - (head - tail) - 1;
558 } else {
559
560 remain = tail - head - 1;
561 dataLen = remain;
562 }
563
564
565
566
567 bytesAvailable = min(remain, bytesAvailable);
568 txwinon(ch);
569 while (bytesAvailable > 0) {
570
571
572
573
574
575
576 dataLen = min(bytesAvailable, dataLen);
577 memcpy_toio(ch->txptr + head, buf, dataLen);
578 buf += dataLen;
579 head += dataLen;
580 amountCopied += dataLen;
581 bytesAvailable -= dataLen;
582
583 if (head >= size) {
584 head = 0;
585 dataLen = tail;
586 }
587 }
588 ch->statusflags |= TXBUSY;
589 globalwinon(ch);
590 writew(head, &bc->tin);
591
592 if ((ch->statusflags & LOWWAIT) == 0) {
593 ch->statusflags |= LOWWAIT;
594 writeb(1, &bc->ilow);
595 }
596 memoff(ch);
597 spin_unlock_irqrestore(&epca_lock, flags);
598 return amountCopied;
599}
600
601static int pc_write_room(struct tty_struct *tty)
602{
603 int remain = 0;
604 struct channel *ch;
605 unsigned long flags;
606 unsigned int head, tail;
607 struct board_chan __iomem *bc;
608
609
610
611
612 ch = verifyChannel(tty);
613 if (ch != NULL) {
614 spin_lock_irqsave(&epca_lock, flags);
615 globalwinon(ch);
616
617 bc = ch->brdchan;
618 head = readw(&bc->tin) & (ch->txbufsize - 1);
619 tail = readw(&bc->tout);
620
621 if (tail != readw(&bc->tout))
622 tail = readw(&bc->tout);
623
624 tail &= (ch->txbufsize - 1);
625 remain = tail - head - 1;
626 if (remain < 0)
627 remain += ch->txbufsize;
628
629 if (remain && (ch->statusflags & LOWWAIT) == 0) {
630 ch->statusflags |= LOWWAIT;
631 writeb(1, &bc->ilow);
632 }
633 memoff(ch);
634 spin_unlock_irqrestore(&epca_lock, flags);
635 }
636
637 return remain;
638}
639
640static int pc_chars_in_buffer(struct tty_struct *tty)
641{
642 int chars;
643 unsigned int ctail, head, tail;
644 int remain;
645 unsigned long flags;
646 struct channel *ch;
647 struct board_chan __iomem *bc;
648
649
650
651
652 ch = verifyChannel(tty);
653 if (ch == NULL)
654 return 0;
655
656 spin_lock_irqsave(&epca_lock, flags);
657 globalwinon(ch);
658
659 bc = ch->brdchan;
660 tail = readw(&bc->tout);
661 head = readw(&bc->tin);
662 ctail = readw(&ch->mailbox->cout);
663
664 if (tail == head && readw(&ch->mailbox->cin) == ctail &&
665 readb(&bc->tbusy) == 0)
666 chars = 0;
667 else {
668 head = readw(&bc->tin) & (ch->txbufsize - 1);
669 tail &= (ch->txbufsize - 1);
670
671
672
673
674
675 remain = tail - head - 1;
676 if (remain < 0)
677 remain += ch->txbufsize;
678 chars = (int)(ch->txbufsize - remain);
679
680
681
682
683
684
685
686 if (!(ch->statusflags & EMPTYWAIT))
687 setup_empty_event(tty, ch);
688 }
689 memoff(ch);
690 spin_unlock_irqrestore(&epca_lock, flags);
691
692 return chars;
693}
694
695static void pc_flush_buffer(struct tty_struct *tty)
696{
697 unsigned int tail;
698 unsigned long flags;
699 struct channel *ch;
700 struct board_chan __iomem *bc;
701
702
703
704
705 ch = verifyChannel(tty);
706 if (ch == NULL)
707 return;
708
709 spin_lock_irqsave(&epca_lock, flags);
710 globalwinon(ch);
711 bc = ch->brdchan;
712 tail = readw(&bc->tout);
713
714 fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0);
715 memoff(ch);
716 spin_unlock_irqrestore(&epca_lock, flags);
717 tty_wakeup(tty);
718}
719
720static void pc_flush_chars(struct tty_struct *tty)
721{
722 struct channel *ch;
723
724
725
726
727 ch = verifyChannel(tty);
728 if (ch != NULL) {
729 unsigned long flags;
730 spin_lock_irqsave(&epca_lock, flags);
731
732
733
734
735 if ((ch->statusflags & TXBUSY) &&
736 !(ch->statusflags & EMPTYWAIT))
737 setup_empty_event(tty, ch);
738 spin_unlock_irqrestore(&epca_lock, flags);
739 }
740}
741
742static int epca_carrier_raised(struct tty_port *port)
743{
744 struct channel *ch = container_of(port, struct channel, port);
745 if (ch->imodem & ch->dcd)
746 return 1;
747 return 0;
748}
749
750static void epca_dtr_rts(struct tty_port *port, int onoff)
751{
752}
753
754static int pc_open(struct tty_struct *tty, struct file *filp)
755{
756 struct channel *ch;
757 struct tty_port *port;
758 unsigned long flags;
759 int line, retval, boardnum;
760 struct board_chan __iomem *bc;
761 unsigned int head;
762
763 line = tty->index;
764 if (line < 0 || line >= nbdevs)
765 return -ENODEV;
766
767 ch = &digi_channels[line];
768 port = &ch->port;
769 boardnum = ch->boardnum;
770
771
772
773
774
775
776
777
778 if (invalid_lilo_config) {
779 if (setup_error_code & INVALID_BOARD_TYPE)
780 printk(KERN_ERR "epca: pc_open: Invalid board type specified in kernel options.\n");
781 if (setup_error_code & INVALID_NUM_PORTS)
782 printk(KERN_ERR "epca: pc_open: Invalid number of ports specified in kernel options.\n");
783 if (setup_error_code & INVALID_MEM_BASE)
784 printk(KERN_ERR "epca: pc_open: Invalid board memory address specified in kernel options.\n");
785 if (setup_error_code & INVALID_PORT_BASE)
786 printk(KERN_ERR "epca; pc_open: Invalid board port address specified in kernel options.\n");
787 if (setup_error_code & INVALID_BOARD_STATUS)
788 printk(KERN_ERR "epca: pc_open: Invalid board status specified in kernel options.\n");
789 if (setup_error_code & INVALID_ALTPIN)
790 printk(KERN_ERR "epca: pc_open: Invalid board altpin specified in kernel options;\n");
791 tty->driver_data = NULL;
792 return -ENODEV;
793 }
794 if (boardnum >= num_cards || boards[boardnum].status == DISABLED) {
795 tty->driver_data = NULL;
796 return(-ENODEV);
797 }
798
799 bc = ch->brdchan;
800 if (bc == NULL) {
801 tty->driver_data = NULL;
802 return -ENODEV;
803 }
804
805 spin_lock_irqsave(&port->lock, flags);
806
807
808
809
810
811 port->count++;
812
813
814
815
816 tty->driver_data = ch;
817 port->tty = tty;
818
819
820
821
822 spin_lock(&epca_lock);
823 globalwinon(ch);
824 ch->statusflags = 0;
825
826
827 ch->imodem = readb(&bc->mstat);
828
829
830
831
832
833 head = readw(&bc->rin);
834 writew(head, &bc->rout);
835
836
837
838
839
840
841
842 epcaparam(tty, ch);
843 memoff(ch);
844 spin_unlock(&epca_lock);
845 port->flags |= ASYNC_INITIALIZED;
846 spin_unlock_irqrestore(&port->lock, flags);
847
848 retval = tty_port_block_til_ready(port, tty, filp);
849 if (retval)
850 return retval;
851
852
853
854
855 spin_lock_irqsave(&port->lock, flags);
856 port->tty = tty;
857 spin_lock(&epca_lock);
858 globalwinon(ch);
859
860 writeb(1, &bc->idata);
861 memoff(ch);
862 spin_unlock(&epca_lock);
863 spin_unlock_irqrestore(&port->lock, flags);
864 return 0;
865}
866
867static int __init epca_module_init(void)
868{
869 return pc_init();
870}
871module_init(epca_module_init);
872
873static struct pci_driver epca_driver;
874
875static void __exit epca_module_exit(void)
876{
877 int count, crd;
878 struct board_info *bd;
879 struct channel *ch;
880
881 del_timer_sync(&epca_timer);
882
883 if (tty_unregister_driver(pc_driver) ||
884 tty_unregister_driver(pc_info)) {
885 printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n");
886 return;
887 }
888 put_tty_driver(pc_driver);
889 put_tty_driver(pc_info);
890
891 for (crd = 0; crd < num_cards; crd++) {
892 bd = &boards[crd];
893 if (!bd) {
894 printk(KERN_ERR "<Error> - Digi : cleanup_module failed\n");
895 return;
896 }
897 ch = card_ptr[crd];
898 for (count = 0; count < bd->numports; count++, ch++) {
899 struct tty_struct *tty = tty_port_tty_get(&ch->port);
900 if (tty) {
901 tty_hangup(tty);
902 tty_kref_put(tty);
903 }
904 }
905 }
906 pci_unregister_driver(&epca_driver);
907}
908module_exit(epca_module_exit);
909
910static const struct tty_operations pc_ops = {
911 .open = pc_open,
912 .close = pc_close,
913 .write = pc_write,
914 .write_room = pc_write_room,
915 .flush_buffer = pc_flush_buffer,
916 .chars_in_buffer = pc_chars_in_buffer,
917 .flush_chars = pc_flush_chars,
918 .ioctl = pc_ioctl,
919 .set_termios = pc_set_termios,
920 .stop = pc_stop,
921 .start = pc_start,
922 .throttle = pc_throttle,
923 .unthrottle = pc_unthrottle,
924 .hangup = pc_hangup,
925 .break_ctl = pc_send_break
926};
927
928static const struct tty_port_operations epca_port_ops = {
929 .carrier_raised = epca_carrier_raised,
930 .dtr_rts = epca_dtr_rts,
931};
932
933static int info_open(struct tty_struct *tty, struct file *filp)
934{
935 return 0;
936}
937
938static struct tty_operations info_ops = {
939 .open = info_open,
940 .ioctl = info_ioctl,
941};
942
943static int __init pc_init(void)
944{
945 int crd;
946 struct board_info *bd;
947 unsigned char board_id = 0;
948 int err = -ENOMEM;
949
950 int pci_boards_found, pci_count;
951
952 pci_count = 0;
953
954 pc_driver = alloc_tty_driver(MAX_ALLOC);
955 if (!pc_driver)
956 goto out1;
957
958 pc_info = alloc_tty_driver(MAX_ALLOC);
959 if (!pc_info)
960 goto out2;
961
962
963
964
965
966
967
968
969 if (!liloconfig) {
970
971 nbdevs = NBDEVS;
972 num_cards = NUMCARDS;
973 memcpy(&boards, &static_boards,
974 sizeof(struct board_info) * NUMCARDS);
975 }
976
977
978
979
980
981
982
983
984
985
986
987
988 printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION);
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005 pci_boards_found = 0;
1006 if (num_cards < MAXBOARDS)
1007 pci_boards_found += init_PCI();
1008 num_cards += pci_boards_found;
1009
1010 pc_driver->owner = THIS_MODULE;
1011 pc_driver->name = "ttyD";
1012 pc_driver->major = DIGI_MAJOR;
1013 pc_driver->minor_start = 0;
1014 pc_driver->type = TTY_DRIVER_TYPE_SERIAL;
1015 pc_driver->subtype = SERIAL_TYPE_NORMAL;
1016 pc_driver->init_termios = tty_std_termios;
1017 pc_driver->init_termios.c_iflag = 0;
1018 pc_driver->init_termios.c_oflag = 0;
1019 pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
1020 pc_driver->init_termios.c_lflag = 0;
1021 pc_driver->init_termios.c_ispeed = 9600;
1022 pc_driver->init_termios.c_ospeed = 9600;
1023 pc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
1024 tty_set_operations(pc_driver, &pc_ops);
1025
1026 pc_info->owner = THIS_MODULE;
1027 pc_info->name = "digi_ctl";
1028 pc_info->major = DIGIINFOMAJOR;
1029 pc_info->minor_start = 0;
1030 pc_info->type = TTY_DRIVER_TYPE_SERIAL;
1031 pc_info->subtype = SERIAL_TYPE_INFO;
1032 pc_info->init_termios = tty_std_termios;
1033 pc_info->init_termios.c_iflag = 0;
1034 pc_info->init_termios.c_oflag = 0;
1035 pc_info->init_termios.c_lflag = 0;
1036 pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
1037 pc_info->init_termios.c_ispeed = 9600;
1038 pc_info->init_termios.c_ospeed = 9600;
1039 pc_info->flags = TTY_DRIVER_REAL_RAW;
1040 tty_set_operations(pc_info, &info_ops);
1041
1042
1043 for (crd = 0; crd < num_cards; crd++) {
1044
1045
1046
1047
1048
1049
1050
1051 bd = &boards[crd];
1052
1053 switch (bd->type) {
1054 case PCXEM:
1055 case EISAXEM:
1056 bd->memwinon = pcxem_memwinon;
1057 bd->memwinoff = pcxem_memwinoff;
1058 bd->globalwinon = pcxem_globalwinon;
1059 bd->txwinon = pcxem_txwinon;
1060 bd->rxwinon = pcxem_rxwinon;
1061 bd->memoff = pcxem_memoff;
1062 bd->assertgwinon = dummy_assertgwinon;
1063 bd->assertmemoff = dummy_assertmemoff;
1064 break;
1065
1066 case PCIXEM:
1067 case PCIXRJ:
1068 case PCIXR:
1069 bd->memwinon = dummy_memwinon;
1070 bd->memwinoff = dummy_memwinoff;
1071 bd->globalwinon = dummy_globalwinon;
1072 bd->txwinon = dummy_txwinon;
1073 bd->rxwinon = dummy_rxwinon;
1074 bd->memoff = dummy_memoff;
1075 bd->assertgwinon = dummy_assertgwinon;
1076 bd->assertmemoff = dummy_assertmemoff;
1077 break;
1078
1079 case PCXE:
1080 case PCXEVE:
1081 bd->memwinon = pcxe_memwinon;
1082 bd->memwinoff = pcxe_memwinoff;
1083 bd->globalwinon = pcxe_globalwinon;
1084 bd->txwinon = pcxe_txwinon;
1085 bd->rxwinon = pcxe_rxwinon;
1086 bd->memoff = pcxe_memoff;
1087 bd->assertgwinon = dummy_assertgwinon;
1088 bd->assertmemoff = dummy_assertmemoff;
1089 break;
1090
1091 case PCXI:
1092 case PC64XE:
1093 bd->memwinon = pcxi_memwinon;
1094 bd->memwinoff = pcxi_memwinoff;
1095 bd->globalwinon = pcxi_globalwinon;
1096 bd->txwinon = pcxi_txwinon;
1097 bd->rxwinon = pcxi_rxwinon;
1098 bd->memoff = pcxi_memoff;
1099 bd->assertgwinon = pcxi_assertgwinon;
1100 bd->assertmemoff = pcxi_assertmemoff;
1101 break;
1102
1103 default:
1104 break;
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114 switch (bd->type) {
1115 case PCXE:
1116 case PCXEVE:
1117 case PC64XE:
1118 bd->memory_seg = 0xf000;
1119 break;
1120
1121 case PCXI:
1122 board_id = inb((int)bd->port);
1123 if ((board_id & 0x1) == 0x1) {
1124
1125
1126 if ((board_id & 0x30) == 0)
1127 bd->memory_seg = 0xf000;
1128
1129
1130 if ((board_id & 0x30) == 0x10)
1131 bd->memory_seg = 0xe000;
1132
1133
1134 if ((board_id & 0x30) == 0x20)
1135 bd->memory_seg = 0xc000;
1136
1137
1138 if ((board_id & 0x30) == 0x30)
1139 bd->memory_seg = 0x8000;
1140 } else
1141 printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port);
1142 break;
1143 }
1144 }
1145
1146 err = tty_register_driver(pc_driver);
1147 if (err) {
1148 printk(KERN_ERR "Couldn't register Digi PC/ driver");
1149 goto out3;
1150 }
1151
1152 err = tty_register_driver(pc_info);
1153 if (err) {
1154 printk(KERN_ERR "Couldn't register Digi PC/ info ");
1155 goto out4;
1156 }
1157
1158
1159 init_timer(&epca_timer);
1160 epca_timer.function = epcapoll;
1161 mod_timer(&epca_timer, jiffies + HZ/25);
1162 return 0;
1163
1164out4:
1165 tty_unregister_driver(pc_driver);
1166out3:
1167 put_tty_driver(pc_info);
1168out2:
1169 put_tty_driver(pc_driver);
1170out1:
1171 return err;
1172}
1173
1174static void post_fep_init(unsigned int crd)
1175{
1176 int i;
1177 void __iomem *memaddr;
1178 struct global_data __iomem *gd;
1179 struct board_info *bd;
1180 struct board_chan __iomem *bc;
1181 struct channel *ch;
1182 int shrinkmem = 0, lowwater;
1183
1184
1185
1186
1187
1188 bd = &boards[crd];
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 if (bd->type >= PCIXEM) {
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214 bd->numports = readw(bd->re_map_membase + XEMPORTS);
1215 epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports");
1216 nbdevs += (bd->numports);
1217 } else {
1218
1219
1220 bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000);
1221 }
1222
1223 if (crd != 0)
1224 card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports;
1225 else
1226 card_ptr[crd] = &digi_channels[crd];
1227
1228 ch = card_ptr[crd];
1229 epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range");
1230
1231 memaddr = bd->re_map_membase;
1232
1233
1234
1235
1236
1237
1238 bc = memaddr + CHANSTRUCT;
1239
1240
1241
1242
1243
1244
1245 gd = memaddr + GLOBAL;
1246
1247
1248
1249
1250
1251 if ((bd->type == PCXEVE || bd->type == PCXE) &&
1252 (readw(memaddr + XEPORTS) < 3))
1253 shrinkmem = 1;
1254 if (bd->type < PCIXEM)
1255 if (!request_region((int)bd->port, 4, board_desc[bd->type]))
1256 return;
1257 memwinon(bd, 0);
1258
1259
1260
1261
1262
1263 for (i = 0; i < bd->numports; i++, ch++, bc++) {
1264 unsigned long flags;
1265 u16 tseg, rseg;
1266
1267 tty_port_init(&ch->port);
1268 ch->port.ops = &epca_port_ops;
1269 ch->brdchan = bc;
1270 ch->mailbox = gd;
1271 INIT_WORK(&ch->tqueue, do_softint);
1272 ch->board = &boards[crd];
1273
1274 spin_lock_irqsave(&epca_lock, flags);
1275 switch (bd->type) {
1276
1277
1278
1279
1280
1281
1282 case EISAXEM:
1283 case PCXEM:
1284 case PCIXEM:
1285 case PCIXRJ:
1286 case PCIXR:
1287 ch->m_rts = 0x02;
1288 ch->m_dcd = 0x80;
1289 ch->m_dsr = 0x20;
1290 ch->m_cts = 0x10;
1291 ch->m_ri = 0x40;
1292 ch->m_dtr = 0x01;
1293 break;
1294
1295 case PCXE:
1296 case PCXEVE:
1297 case PCXI:
1298 case PC64XE:
1299 ch->m_rts = 0x02;
1300 ch->m_dcd = 0x08;
1301 ch->m_dsr = 0x10;
1302 ch->m_cts = 0x20;
1303 ch->m_ri = 0x40;
1304 ch->m_dtr = 0x80;
1305 break;
1306 }
1307
1308 if (boards[crd].altpin) {
1309 ch->dsr = ch->m_dcd;
1310 ch->dcd = ch->m_dsr;
1311 ch->digiext.digi_flags |= DIGI_ALTPIN;
1312 } else {
1313 ch->dcd = ch->m_dcd;
1314 ch->dsr = ch->m_dsr;
1315 }
1316
1317 ch->boardnum = crd;
1318 ch->channelnum = i;
1319 ch->magic = EPCA_MAGIC;
1320 tty_port_tty_set(&ch->port, NULL);
1321
1322 if (shrinkmem) {
1323 fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
1324 shrinkmem = 0;
1325 }
1326
1327 tseg = readw(&bc->tseg);
1328 rseg = readw(&bc->rseg);
1329
1330 switch (bd->type) {
1331 case PCIXEM:
1332 case PCIXRJ:
1333 case PCIXR:
1334
1335 ch->txptr = memaddr + ((tseg << 4) & 0x1fffff);
1336 ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff);
1337 ch->txwin = FEPWIN | (tseg >> 11);
1338 ch->rxwin = FEPWIN | (rseg >> 11);
1339 break;
1340
1341 case PCXEM:
1342 case EISAXEM:
1343
1344
1345 ch->txptr = memaddr + ((tseg << 4) & 0x7fff);
1346 ch->rxptr = memaddr + ((rseg << 4) & 0x7fff);
1347 ch->txwin = FEPWIN | (tseg >> 11);
1348 ch->rxwin = FEPWIN | (rseg >> 11);
1349 break;
1350
1351 case PCXEVE:
1352 case PCXE:
1353 ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4)
1354 & 0x1fff);
1355 ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
1356 ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4)
1357 & 0x1fff);
1358 ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9);
1359 break;
1360
1361 case PCXI:
1362 case PC64XE:
1363 ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4);
1364 ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4);
1365 ch->txwin = ch->rxwin = 0;
1366 break;
1367 }
1368
1369 ch->txbufhead = 0;
1370 ch->txbufsize = readw(&bc->tmax) + 1;
1371
1372 ch->rxbufhead = 0;
1373 ch->rxbufsize = readw(&bc->rmax) + 1;
1374
1375 lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2);
1376
1377
1378 fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);
1379
1380
1381 fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0);
1382
1383
1384 fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0);
1385
1386 writew(100, &bc->edelay);
1387 writeb(1, &bc->idata);
1388
1389 ch->startc = readb(&bc->startc);
1390 ch->stopc = readb(&bc->stopc);
1391 ch->startca = readb(&bc->startca);
1392 ch->stopca = readb(&bc->stopca);
1393
1394 ch->fepcflag = 0;
1395 ch->fepiflag = 0;
1396 ch->fepoflag = 0;
1397 ch->fepstartc = 0;
1398 ch->fepstopc = 0;
1399 ch->fepstartca = 0;
1400 ch->fepstopca = 0;
1401
1402 ch->port.close_delay = 50;
1403
1404 spin_unlock_irqrestore(&epca_lock, flags);
1405 }
1406
1407 printk(KERN_INFO
1408 "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
1409 VERSION, board_desc[bd->type], (long)bd->port,
1410 (long)bd->membase, bd->numports);
1411 memwinoff(bd, 0);
1412}
1413
1414static void epcapoll(unsigned long ignored)
1415{
1416 unsigned long flags;
1417 int crd;
1418 unsigned int head, tail;
1419 struct channel *ch;
1420 struct board_info *bd;
1421
1422
1423
1424
1425
1426
1427
1428
1429 for (crd = 0; crd < num_cards; crd++) {
1430 bd = &boards[crd];
1431 ch = card_ptr[crd];
1432
1433 if ((bd->status == DISABLED) || digi_poller_inhibited)
1434 continue;
1435
1436
1437
1438
1439
1440
1441 spin_lock_irqsave(&epca_lock, flags);
1442
1443 assertmemoff(ch);
1444
1445 globalwinon(ch);
1446
1447
1448
1449
1450
1451 head = readw(&ch->mailbox->ein);
1452 tail = readw(&ch->mailbox->eout);
1453
1454
1455 if (head != tail)
1456 doevent(crd);
1457 memoff(ch);
1458
1459 spin_unlock_irqrestore(&epca_lock, flags);
1460 }
1461 mod_timer(&epca_timer, jiffies + (HZ / 25));
1462}
1463
1464static void doevent(int crd)
1465{
1466 void __iomem *eventbuf;
1467 struct channel *ch, *chan0;
1468 static struct tty_struct *tty;
1469 struct board_info *bd;
1470 struct board_chan __iomem *bc;
1471 unsigned int tail, head;
1472 int event, channel;
1473 int mstat, lstat;
1474
1475
1476
1477
1478
1479 bd = &boards[crd];
1480
1481 chan0 = card_ptr[crd];
1482 epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range");
1483 assertgwinon(chan0);
1484 while ((tail = readw(&chan0->mailbox->eout)) !=
1485 (head = readw(&chan0->mailbox->ein))) {
1486
1487 assertgwinon(chan0);
1488 eventbuf = bd->re_map_membase + tail + ISTART;
1489
1490 channel = readb(eventbuf);
1491
1492 event = readb(eventbuf + 1);
1493
1494
1495
1496
1497
1498
1499 mstat = readb(eventbuf + 2);
1500 lstat = readb(eventbuf + 3);
1501
1502 ch = chan0 + channel;
1503 if ((unsigned)channel >= bd->numports || !ch) {
1504 if (channel >= bd->numports)
1505 ch = chan0;
1506 bc = ch->brdchan;
1507 goto next;
1508 }
1509
1510 bc = ch->brdchan;
1511 if (bc == NULL)
1512 goto next;
1513
1514 tty = tty_port_tty_get(&ch->port);
1515 if (event & DATA_IND) {
1516 receive_data(ch, tty);
1517 assertgwinon(ch);
1518 }
1519
1520 if (event & MODEMCHG_IND) {
1521
1522 ch->imodem = mstat;
1523 if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) {
1524
1525 if (mstat & ch->dcd)
1526 wake_up_interruptible(&ch->port.open_wait);
1527 else
1528 pc_sched_event(ch, EPCA_EVENT_HANGUP);
1529 }
1530 }
1531 if (tty) {
1532 if (event & BREAK_IND) {
1533
1534 tty_insert_flip_char(tty, 0, TTY_BREAK);
1535 tty_schedule_flip(tty);
1536 } else if (event & LOWTX_IND) {
1537 if (ch->statusflags & LOWWAIT) {
1538 ch->statusflags &= ~LOWWAIT;
1539 tty_wakeup(tty);
1540 }
1541 } else if (event & EMPTYTX_IND) {
1542
1543
1544 ch->statusflags &= ~TXBUSY;
1545 if (ch->statusflags & EMPTYWAIT) {
1546 ch->statusflags &= ~EMPTYWAIT;
1547 tty_wakeup(tty);
1548 }
1549 }
1550 tty_kref_put(tty);
1551 }
1552next:
1553 globalwinon(ch);
1554 BUG_ON(!bc);
1555 writew(1, &bc->idata);
1556 writew((tail + 4) & (IMAX - ISTART - 4), &chan0->mailbox->eout);
1557 globalwinon(chan0);
1558 }
1559}
1560
1561static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
1562 int byte2, int ncmds, int bytecmd)
1563{
1564 unchar __iomem *memaddr;
1565 unsigned int head, cmdTail, cmdStart, cmdMax;
1566 long count;
1567 int n;
1568
1569
1570
1571 if (ch->board->status == DISABLED)
1572 return;
1573 assertgwinon(ch);
1574
1575 head = readw(&ch->mailbox->cin);
1576
1577 cmdStart = readw(&ch->mailbox->cstart);
1578
1579
1580
1581
1582
1583 cmdMax = (cmdStart + 4 + readw(&ch->mailbox->cmax));
1584 memaddr = ch->board->re_map_membase;
1585
1586 if (head >= (cmdMax - cmdStart) || (head & 03)) {
1587 printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n",
1588 __LINE__, cmd, head);
1589 printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n",
1590 __LINE__, cmdMax, cmdStart);
1591 return;
1592 }
1593 if (bytecmd) {
1594 writeb(cmd, memaddr + head + cmdStart + 0);
1595 writeb(ch->channelnum, memaddr + head + cmdStart + 1);
1596
1597 writeb(word_or_byte, memaddr + head + cmdStart + 2);
1598
1599 writeb(byte2, memaddr + head + cmdStart + 3);
1600 } else {
1601 writeb(cmd, memaddr + head + cmdStart + 0);
1602 writeb(ch->channelnum, memaddr + head + cmdStart + 1);
1603 writeb(word_or_byte, memaddr + head + cmdStart + 2);
1604 }
1605 head = (head + 4) & (cmdMax - cmdStart - 4);
1606 writew(head, &ch->mailbox->cin);
1607 count = FEPTIMEOUT;
1608
1609 for (;;) {
1610 count--;
1611 if (count == 0) {
1612 printk(KERN_ERR "<Error> - Fep not responding in fepcmd()\n");
1613 return;
1614 }
1615 head = readw(&ch->mailbox->cin);
1616 cmdTail = readw(&ch->mailbox->cout);
1617 n = (head - cmdTail) & (cmdMax - cmdStart - 4);
1618
1619
1620
1621
1622 if (n <= ncmds * (sizeof(short) * 4))
1623 break;
1624 }
1625}
1626
1627
1628
1629
1630
1631
1632
1633static unsigned termios2digi_h(struct channel *ch, unsigned cflag)
1634{
1635 unsigned res = 0;
1636
1637 if (cflag & CRTSCTS) {
1638 ch->digiext.digi_flags |= (RTSPACE | CTSPACE);
1639 res |= ((ch->m_cts) | (ch->m_rts));
1640 }
1641
1642 if (ch->digiext.digi_flags & RTSPACE)
1643 res |= ch->m_rts;
1644
1645 if (ch->digiext.digi_flags & DTRPACE)
1646 res |= ch->m_dtr;
1647
1648 if (ch->digiext.digi_flags & CTSPACE)
1649 res |= ch->m_cts;
1650
1651 if (ch->digiext.digi_flags & DSRPACE)
1652 res |= ch->dsr;
1653
1654 if (ch->digiext.digi_flags & DCDPACE)
1655 res |= ch->dcd;
1656
1657 if (res & (ch->m_rts))
1658 ch->digiext.digi_flags |= RTSPACE;
1659
1660 if (res & (ch->m_cts))
1661 ch->digiext.digi_flags |= CTSPACE;
1662
1663 return res;
1664}
1665
1666static unsigned termios2digi_i(struct channel *ch, unsigned iflag)
1667{
1668 unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
1669 INPCK | ISTRIP | IXON | IXANY | IXOFF);
1670 if (ch->digiext.digi_flags & DIGI_AIXON)
1671 res |= IAIXON;
1672 return res;
1673}
1674
1675static unsigned termios2digi_c(struct channel *ch, unsigned cflag)
1676{
1677 unsigned res = 0;
1678 if (cflag & CBAUDEX) {
1679 ch->digiext.digi_flags |= DIGI_FAST;
1680
1681
1682
1683
1684 res |= FEP_HUPCL;
1685 } else
1686 ch->digiext.digi_flags &= ~DIGI_FAST;
1687
1688
1689
1690
1691
1692
1693 res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE);
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714 if (cflag & CBAUDEX) {
1715
1716
1717
1718
1719
1720
1721 if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) ||
1722 (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX))))
1723 res += 1;
1724 }
1725 return res;
1726}
1727
1728
1729static void epcaparam(struct tty_struct *tty, struct channel *ch)
1730{
1731 unsigned int cmdHead;
1732 struct ktermios *ts;
1733 struct board_chan __iomem *bc;
1734 unsigned mval, hflow, cflag, iflag;
1735
1736 bc = ch->brdchan;
1737 epcaassert(bc != NULL, "bc out of range");
1738
1739 assertgwinon(ch);
1740 ts = tty->termios;
1741 if ((ts->c_cflag & CBAUD) == 0) {
1742 cmdHead = readw(&bc->rin);
1743 writew(cmdHead, &bc->rout);
1744 cmdHead = readw(&bc->tin);
1745
1746
1747
1748
1749
1750
1751 fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0);
1752 mval = 0;
1753 } else {
1754
1755
1756
1757
1758 cflag = termios2digi_c(ch, ts->c_cflag);
1759 if (cflag != ch->fepcflag) {
1760 ch->fepcflag = cflag;
1761
1762 fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0);
1763 }
1764
1765
1766
1767
1768
1769 if (ts->c_cflag & CLOCAL)
1770 clear_bit(ASYNCB_CHECK_CD, &ch->port.flags);
1771 else
1772 set_bit(ASYNCB_CHECK_CD, &ch->port.flags);
1773 mval = ch->m_dtr | ch->m_rts;
1774 }
1775 iflag = termios2digi_i(ch, ts->c_iflag);
1776
1777 if (iflag != ch->fepiflag) {
1778 ch->fepiflag = iflag;
1779
1780
1781
1782
1783
1784
1785
1786
1787 fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
1788 }
1789
1790
1791
1792
1793
1794 writeb(ch->dcd, &bc->mint);
1795 if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD))
1796 if (ch->digiext.digi_flags & DIGI_FORCEDCD)
1797 writeb(0, &bc->mint);
1798 ch->imodem = readb(&bc->mstat);
1799 hflow = termios2digi_h(ch, ts->c_cflag);
1800 if (hflow != ch->hflow) {
1801 ch->hflow = hflow;
1802
1803
1804
1805
1806 fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1);
1807 }
1808 mval ^= ch->modemfake & (mval ^ ch->modem);
1809
1810 if (ch->omodem ^ mval) {
1811 ch->omodem = mval;
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821 fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1);
1822 fepcmd(ch, SETMODEM, mval, 0, 0, 1);
1823 }
1824 if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) {
1825 ch->fepstartc = ch->startc;
1826 ch->fepstopc = ch->stopc;
1827
1828
1829
1830
1831 fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
1832 }
1833 if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) {
1834 ch->fepstartca = ch->startca;
1835 ch->fepstopca = ch->stopca;
1836
1837
1838
1839
1840 fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
1841 }
1842}
1843
1844
1845static void receive_data(struct channel *ch, struct tty_struct *tty)
1846{
1847 unchar *rptr;
1848 struct ktermios *ts = NULL;
1849 struct board_chan __iomem *bc;
1850 int dataToRead, wrapgap, bytesAvailable;
1851 unsigned int tail, head;
1852 unsigned int wrapmask;
1853
1854
1855
1856
1857
1858 globalwinon(ch);
1859 if (ch->statusflags & RXSTOPPED)
1860 return;
1861 if (tty)
1862 ts = tty->termios;
1863 bc = ch->brdchan;
1864 BUG_ON(!bc);
1865 wrapmask = ch->rxbufsize - 1;
1866
1867
1868
1869
1870
1871 head = readw(&bc->rin);
1872 head &= wrapmask;
1873 tail = readw(&bc->rout) & wrapmask;
1874
1875 bytesAvailable = (head - tail) & wrapmask;
1876 if (bytesAvailable == 0)
1877 return;
1878
1879
1880 if (!tty || !ts || !(ts->c_cflag & CREAD)) {
1881 writew(head, &bc->rout);
1882 return;
1883 }
1884
1885 if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0)
1886 return;
1887
1888 if (readb(&bc->orun)) {
1889 writeb(0, &bc->orun);
1890 printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",
1891 tty->name);
1892 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1893 }
1894 rxwinon(ch);
1895 while (bytesAvailable > 0) {
1896
1897 wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
1898
1899
1900
1901
1902
1903 dataToRead = (wrapgap < bytesAvailable) ? wrapgap
1904 : bytesAvailable;
1905
1906 dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead);
1907 if (dataToRead == 0)
1908 break;
1909
1910
1911
1912
1913 memcpy_fromio(rptr, ch->rxptr + tail, dataToRead);
1914 tail = (tail + dataToRead) & wrapmask;
1915 bytesAvailable -= dataToRead;
1916 }
1917 globalwinon(ch);
1918 writew(tail, &bc->rout);
1919
1920 tty_schedule_flip(tty);
1921}
1922
1923static int info_ioctl(struct tty_struct *tty, struct file *file,
1924 unsigned int cmd, unsigned long arg)
1925{
1926 switch (cmd) {
1927 case DIGI_GETINFO:
1928 {
1929 struct digi_info di;
1930 int brd;
1931
1932 if (get_user(brd, (unsigned int __user *)arg))
1933 return -EFAULT;
1934 if (brd < 0 || brd >= num_cards || num_cards == 0)
1935 return -ENODEV;
1936
1937 memset(&di, 0, sizeof(di));
1938
1939 di.board = brd;
1940 di.status = boards[brd].status;
1941 di.type = boards[brd].type ;
1942 di.numports = boards[brd].numports ;
1943
1944 di.port = (unsigned char *)boards[brd].port ;
1945 di.membase = (unsigned char *)boards[brd].membase ;
1946
1947 if (copy_to_user((void __user *)arg, &di, sizeof(di)))
1948 return -EFAULT;
1949 break;
1950
1951 }
1952
1953 case DIGI_POLLER:
1954 {
1955 int brd = arg & 0xff000000 >> 16;
1956 unsigned char state = arg & 0xff;
1957
1958 if (brd < 0 || brd >= num_cards) {
1959 printk(KERN_ERR "epca: DIGI POLLER : brd not valid!\n");
1960 return -ENODEV;
1961 }
1962 digi_poller_inhibited = state;
1963 break;
1964 }
1965
1966 case DIGI_INIT:
1967 {
1968
1969
1970
1971
1972
1973
1974
1975 int crd;
1976 for (crd = 0; crd < num_cards; crd++)
1977 post_fep_init(crd);
1978 break;
1979 }
1980 default:
1981 return -ENOTTY;
1982 }
1983 return 0;
1984}
1985
1986static int pc_tiocmget(struct tty_struct *tty, struct file *file)
1987{
1988 struct channel *ch = tty->driver_data;
1989 struct board_chan __iomem *bc;
1990 unsigned int mstat, mflag = 0;
1991 unsigned long flags;
1992
1993 if (ch)
1994 bc = ch->brdchan;
1995 else
1996 return -EINVAL;
1997
1998 spin_lock_irqsave(&epca_lock, flags);
1999 globalwinon(ch);
2000 mstat = readb(&bc->mstat);
2001 memoff(ch);
2002 spin_unlock_irqrestore(&epca_lock, flags);
2003
2004 if (mstat & ch->m_dtr)
2005 mflag |= TIOCM_DTR;
2006 if (mstat & ch->m_rts)
2007 mflag |= TIOCM_RTS;
2008 if (mstat & ch->m_cts)
2009 mflag |= TIOCM_CTS;
2010 if (mstat & ch->dsr)
2011 mflag |= TIOCM_DSR;
2012 if (mstat & ch->m_ri)
2013 mflag |= TIOCM_RI;
2014 if (mstat & ch->dcd)
2015 mflag |= TIOCM_CD;
2016 return mflag;
2017}
2018
2019static int pc_tiocmset(struct tty_struct *tty, struct file *file,
2020 unsigned int set, unsigned int clear)
2021{
2022 struct channel *ch = tty->driver_data;
2023 unsigned long flags;
2024
2025 if (!ch)
2026 return -EINVAL;
2027
2028 spin_lock_irqsave(&epca_lock, flags);
2029
2030
2031
2032
2033
2034 if (set & TIOCM_RTS) {
2035 ch->modemfake |= ch->m_rts;
2036 ch->modem |= ch->m_rts;
2037 }
2038 if (set & TIOCM_DTR) {
2039 ch->modemfake |= ch->m_dtr;
2040 ch->modem |= ch->m_dtr;
2041 }
2042 if (clear & TIOCM_RTS) {
2043 ch->modemfake |= ch->m_rts;
2044 ch->modem &= ~ch->m_rts;
2045 }
2046 if (clear & TIOCM_DTR) {
2047 ch->modemfake |= ch->m_dtr;
2048 ch->modem &= ~ch->m_dtr;
2049 }
2050 globalwinon(ch);
2051
2052
2053
2054
2055 epcaparam(tty, ch);
2056 memoff(ch);
2057 spin_unlock_irqrestore(&epca_lock, flags);
2058 return 0;
2059}
2060
2061static int pc_ioctl(struct tty_struct *tty, struct file *file,
2062 unsigned int cmd, unsigned long arg)
2063{
2064 digiflow_t dflow;
2065 unsigned long flags;
2066 unsigned int mflag, mstat;
2067 unsigned char startc, stopc;
2068 struct board_chan __iomem *bc;
2069 struct channel *ch = tty->driver_data;
2070 void __user *argp = (void __user *)arg;
2071
2072 if (ch)
2073 bc = ch->brdchan;
2074 else
2075 return -EINVAL;
2076 switch (cmd) {
2077 case TIOCMODG:
2078 mflag = pc_tiocmget(tty, file);
2079 if (put_user(mflag, (unsigned long __user *)argp))
2080 return -EFAULT;
2081 break;
2082 case TIOCMODS:
2083 if (get_user(mstat, (unsigned __user *)argp))
2084 return -EFAULT;
2085 return pc_tiocmset(tty, file, mstat, ~mstat);
2086 case TIOCSDTR:
2087 spin_lock_irqsave(&epca_lock, flags);
2088 ch->omodem |= ch->m_dtr;
2089 globalwinon(ch);
2090 fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1);
2091 memoff(ch);
2092 spin_unlock_irqrestore(&epca_lock, flags);
2093 break;
2094
2095 case TIOCCDTR:
2096 spin_lock_irqsave(&epca_lock, flags);
2097 ch->omodem &= ~ch->m_dtr;
2098 globalwinon(ch);
2099 fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1);
2100 memoff(ch);
2101 spin_unlock_irqrestore(&epca_lock, flags);
2102 break;
2103 case DIGI_GETA:
2104 if (copy_to_user(argp, &ch->digiext, sizeof(digi_t)))
2105 return -EFAULT;
2106 break;
2107 case DIGI_SETAW:
2108 case DIGI_SETAF:
2109 lock_kernel();
2110 if (cmd == DIGI_SETAW) {
2111
2112
2113 spin_lock_irqsave(&epca_lock, flags);
2114 setup_empty_event(tty, ch);
2115 spin_unlock_irqrestore(&epca_lock, flags);
2116 tty_wait_until_sent(tty, 0);
2117 } else {
2118
2119 if (tty->ldisc->ops->flush_buffer)
2120 tty->ldisc->ops->flush_buffer(tty);
2121 }
2122 unlock_kernel();
2123
2124 case DIGI_SETA:
2125 if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))
2126 return -EFAULT;
2127
2128 if (ch->digiext.digi_flags & DIGI_ALTPIN) {
2129 ch->dcd = ch->m_dsr;
2130 ch->dsr = ch->m_dcd;
2131 } else {
2132 ch->dcd = ch->m_dcd;
2133 ch->dsr = ch->m_dsr;
2134 }
2135
2136 spin_lock_irqsave(&epca_lock, flags);
2137 globalwinon(ch);
2138
2139
2140
2141
2142
2143
2144 epcaparam(tty, ch);
2145 memoff(ch);
2146 spin_unlock_irqrestore(&epca_lock, flags);
2147 break;
2148
2149 case DIGI_GETFLOW:
2150 case DIGI_GETAFLOW:
2151 spin_lock_irqsave(&epca_lock, flags);
2152 globalwinon(ch);
2153 if (cmd == DIGI_GETFLOW) {
2154 dflow.startc = readb(&bc->startc);
2155 dflow.stopc = readb(&bc->stopc);
2156 } else {
2157 dflow.startc = readb(&bc->startca);
2158 dflow.stopc = readb(&bc->stopca);
2159 }
2160 memoff(ch);
2161 spin_unlock_irqrestore(&epca_lock, flags);
2162
2163 if (copy_to_user(argp, &dflow, sizeof(dflow)))
2164 return -EFAULT;
2165 break;
2166
2167 case DIGI_SETAFLOW:
2168 case DIGI_SETFLOW:
2169 if (cmd == DIGI_SETFLOW) {
2170 startc = ch->startc;
2171 stopc = ch->stopc;
2172 } else {
2173 startc = ch->startca;
2174 stopc = ch->stopca;
2175 }
2176
2177 if (copy_from_user(&dflow, argp, sizeof(dflow)))
2178 return -EFAULT;
2179
2180 if (dflow.startc != startc || dflow.stopc != stopc) {
2181
2182 spin_lock_irqsave(&epca_lock, flags);
2183 globalwinon(ch);
2184
2185 if (cmd == DIGI_SETFLOW) {
2186 ch->fepstartc = ch->startc = dflow.startc;
2187 ch->fepstopc = ch->stopc = dflow.stopc;
2188 fepcmd(ch, SONOFFC, ch->fepstartc,
2189 ch->fepstopc, 0, 1);
2190 } else {
2191 ch->fepstartca = ch->startca = dflow.startc;
2192 ch->fepstopca = ch->stopca = dflow.stopc;
2193 fepcmd(ch, SAUXONOFFC, ch->fepstartca,
2194 ch->fepstopca, 0, 1);
2195 }
2196
2197 if (ch->statusflags & TXSTOPPED)
2198 pc_start(tty);
2199
2200 memoff(ch);
2201 spin_unlock_irqrestore(&epca_lock, flags);
2202 }
2203 break;
2204 default:
2205 return -ENOIOCTLCMD;
2206 }
2207 return 0;
2208}
2209
2210static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
2211{
2212 struct channel *ch;
2213 unsigned long flags;
2214
2215
2216
2217
2218 ch = verifyChannel(tty);
2219
2220 if (ch != NULL) {
2221 spin_lock_irqsave(&epca_lock, flags);
2222 globalwinon(ch);
2223 epcaparam(tty, ch);
2224 memoff(ch);
2225 spin_unlock_irqrestore(&epca_lock, flags);
2226
2227 if ((old_termios->c_cflag & CRTSCTS) &&
2228 ((tty->termios->c_cflag & CRTSCTS) == 0))
2229 tty->hw_stopped = 0;
2230
2231 if (!(old_termios->c_cflag & CLOCAL) &&
2232 (tty->termios->c_cflag & CLOCAL))
2233 wake_up_interruptible(&ch->port.open_wait);
2234
2235 }
2236}
2237
2238static void do_softint(struct work_struct *work)
2239{
2240 struct channel *ch = container_of(work, struct channel, tqueue);
2241
2242 if (ch && ch->magic == EPCA_MAGIC) {
2243 struct tty_struct *tty = tty_port_tty_get(&ch->port);
2244
2245 if (tty && tty->driver_data) {
2246 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
2247 tty_hangup(tty);
2248 wake_up_interruptible(&ch->port.open_wait);
2249 clear_bit(ASYNCB_NORMAL_ACTIVE,
2250 &ch->port.flags);
2251 }
2252 }
2253 tty_kref_put(tty);
2254 }
2255}
2256
2257
2258
2259
2260
2261static void pc_stop(struct tty_struct *tty)
2262{
2263 struct channel *ch;
2264 unsigned long flags;
2265
2266
2267
2268
2269 ch = verifyChannel(tty);
2270 if (ch != NULL) {
2271 spin_lock_irqsave(&epca_lock, flags);
2272 if ((ch->statusflags & TXSTOPPED) == 0) {
2273
2274 globalwinon(ch);
2275
2276 fepcmd(ch, PAUSETX, 0, 0, 0, 0);
2277 ch->statusflags |= TXSTOPPED;
2278 memoff(ch);
2279 }
2280 spin_unlock_irqrestore(&epca_lock, flags);
2281 }
2282}
2283
2284static void pc_start(struct tty_struct *tty)
2285{
2286 struct channel *ch;
2287
2288
2289
2290
2291 ch = verifyChannel(tty);
2292 if (ch != NULL) {
2293 unsigned long flags;
2294 spin_lock_irqsave(&epca_lock, flags);
2295
2296
2297 if (ch->statusflags & TXSTOPPED) {
2298
2299 struct board_chan __iomem *bc;
2300 globalwinon(ch);
2301 bc = ch->brdchan;
2302 if (ch->statusflags & LOWWAIT)
2303 writeb(1, &bc->ilow);
2304
2305 fepcmd(ch, RESUMETX, 0, 0, 0, 0);
2306 ch->statusflags &= ~TXSTOPPED;
2307 memoff(ch);
2308 }
2309 spin_unlock_irqrestore(&epca_lock, flags);
2310 }
2311}
2312
2313
2314
2315
2316
2317
2318
2319
2320static void pc_throttle(struct tty_struct *tty)
2321{
2322 struct channel *ch;
2323 unsigned long flags;
2324
2325
2326
2327
2328 ch = verifyChannel(tty);
2329 if (ch != NULL) {
2330 spin_lock_irqsave(&epca_lock, flags);
2331 if ((ch->statusflags & RXSTOPPED) == 0) {
2332 globalwinon(ch);
2333 fepcmd(ch, PAUSERX, 0, 0, 0, 0);
2334 ch->statusflags |= RXSTOPPED;
2335 memoff(ch);
2336 }
2337 spin_unlock_irqrestore(&epca_lock, flags);
2338 }
2339}
2340
2341static void pc_unthrottle(struct tty_struct *tty)
2342{
2343 struct channel *ch;
2344 unsigned long flags;
2345
2346
2347
2348
2349 ch = verifyChannel(tty);
2350 if (ch != NULL) {
2351
2352
2353 spin_lock_irqsave(&epca_lock, flags);
2354 if (ch->statusflags & RXSTOPPED) {
2355 globalwinon(ch);
2356 fepcmd(ch, RESUMERX, 0, 0, 0, 0);
2357 ch->statusflags &= ~RXSTOPPED;
2358 memoff(ch);
2359 }
2360 spin_unlock_irqrestore(&epca_lock, flags);
2361 }
2362}
2363
2364static int pc_send_break(struct tty_struct *tty, int msec)
2365{
2366 struct channel *ch = tty->driver_data;
2367 unsigned long flags;
2368
2369 if (msec == -1)
2370 msec = 0xFFFF;
2371 else if (msec > 0xFFFE)
2372 msec = 0xFFFE;
2373 else if (msec < 1)
2374 msec = 1;
2375
2376 spin_lock_irqsave(&epca_lock, flags);
2377 globalwinon(ch);
2378
2379
2380
2381
2382
2383
2384
2385 fepcmd(ch, SENDBREAK, msec, 0, 10, 0);
2386 memoff(ch);
2387 spin_unlock_irqrestore(&epca_lock, flags);
2388 return 0;
2389}
2390
2391
2392static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
2393{
2394 struct board_chan __iomem *bc = ch->brdchan;
2395
2396 globalwinon(ch);
2397 ch->statusflags |= EMPTYWAIT;
2398
2399
2400
2401
2402 writeb(1, &bc->iempty);
2403 memoff(ch);
2404}
2405
2406#ifndef MODULE
2407static void __init epca_setup(char *str, int *ints)
2408{
2409 struct board_info board;
2410 int index, loop, last;
2411 char *temp, *t2;
2412 unsigned len;
2413
2414
2415
2416
2417
2418
2419
2420 if (!liloconfig)
2421 liloconfig = 1;
2422
2423 memset(&board, 0, sizeof(board));
2424
2425
2426
2427 for (last = 0, index = 1; index <= ints[0]; index++)
2428 switch (index) {
2429 case 1:
2430 board.status = ints[index];
2431
2432
2433
2434
2435
2436 if (board.status == 2) {
2437
2438 nbdevs = 0;
2439 num_cards = 0;
2440 return;
2441 }
2442
2443 if (board.status > 2) {
2444 printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n",
2445 board.status);
2446 invalid_lilo_config = 1;
2447 setup_error_code |= INVALID_BOARD_STATUS;
2448 return;
2449 }
2450 last = index;
2451 break;
2452 case 2:
2453 board.type = ints[index];
2454 if (board.type >= PCIXEM) {
2455 printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type);
2456 invalid_lilo_config = 1;
2457 setup_error_code |= INVALID_BOARD_TYPE;
2458 return;
2459 }
2460 last = index;
2461 break;
2462 case 3:
2463 board.altpin = ints[index];
2464 if (board.altpin > 1) {
2465 printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin);
2466 invalid_lilo_config = 1;
2467 setup_error_code |= INVALID_ALTPIN;
2468 return;
2469 }
2470 last = index;
2471 break;
2472
2473 case 4:
2474 board.numports = ints[index];
2475 if (board.numports < 2 || board.numports > 256) {
2476 printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports);
2477 invalid_lilo_config = 1;
2478 setup_error_code |= INVALID_NUM_PORTS;
2479 return;
2480 }
2481 nbdevs += board.numports;
2482 last = index;
2483 break;
2484
2485 case 5:
2486 board.port = ints[index];
2487 if (ints[index] <= 0) {
2488 printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port);
2489 invalid_lilo_config = 1;
2490 setup_error_code |= INVALID_PORT_BASE;
2491 return;
2492 }
2493 last = index;
2494 break;
2495
2496 case 6:
2497 board.membase = ints[index];
2498 if (ints[index] <= 0) {
2499 printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",
2500 (unsigned int)board.membase);
2501 invalid_lilo_config = 1;
2502 setup_error_code |= INVALID_MEM_BASE;
2503 return;
2504 }
2505 last = index;
2506 break;
2507
2508 default:
2509 printk(KERN_ERR "<Error> - epca_setup: Too many integer parms\n");
2510 return;
2511
2512 }
2513
2514 while (str && *str) {
2515
2516 temp = str;
2517
2518 while (*temp && (*temp != ','))
2519 temp++;
2520 if (!*temp)
2521 temp = NULL;
2522 else
2523 *temp++ = 0;
2524
2525 index = last + 1;
2526
2527 switch (index) {
2528 case 1:
2529 len = strlen(str);
2530 if (strncmp("Disable", str, len) == 0)
2531 board.status = 0;
2532 else if (strncmp("Enable", str, len) == 0)
2533 board.status = 1;
2534 else {
2535 printk(KERN_ERR "epca_setup: Invalid status %s\n", str);
2536 invalid_lilo_config = 1;
2537 setup_error_code |= INVALID_BOARD_STATUS;
2538 return;
2539 }
2540 last = index;
2541 break;
2542
2543 case 2:
2544 for (loop = 0; loop < EPCA_NUM_TYPES; loop++)
2545 if (strcmp(board_desc[loop], str) == 0)
2546 break;
2547
2548
2549
2550
2551 if (index < EPCA_NUM_TYPES)
2552 board.type = loop;
2553 else {
2554 printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str);
2555 invalid_lilo_config = 1;
2556 setup_error_code |= INVALID_BOARD_TYPE;
2557 return;
2558 }
2559 last = index;
2560 break;
2561
2562 case 3:
2563 len = strlen(str);
2564 if (strncmp("Disable", str, len) == 0)
2565 board.altpin = 0;
2566 else if (strncmp("Enable", str, len) == 0)
2567 board.altpin = 1;
2568 else {
2569 printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str);
2570 invalid_lilo_config = 1;
2571 setup_error_code |= INVALID_ALTPIN;
2572 return;
2573 }
2574 last = index;
2575 break;
2576
2577 case 4:
2578 t2 = str;
2579 while (isdigit(*t2))
2580 t2++;
2581
2582 if (*t2) {
2583 printk(KERN_ERR "epca_setup: Invalid port count %s\n", str);
2584 invalid_lilo_config = 1;
2585 setup_error_code |= INVALID_NUM_PORTS;
2586 return;
2587 }
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604 board.numports = simple_strtoul(str, NULL, 0);
2605 nbdevs += board.numports;
2606 last = index;
2607 break;
2608
2609 case 5:
2610 t2 = str;
2611 while (isxdigit(*t2))
2612 t2++;
2613
2614 if (*t2) {
2615 printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str);
2616 invalid_lilo_config = 1;
2617 setup_error_code |= INVALID_PORT_BASE;
2618 return;
2619 }
2620
2621 board.port = simple_strtoul(str, NULL, 16);
2622 last = index;
2623 break;
2624
2625 case 6:
2626 t2 = str;
2627 while (isxdigit(*t2))
2628 t2++;
2629
2630 if (*t2) {
2631 printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str);
2632 invalid_lilo_config = 1;
2633 setup_error_code |= INVALID_MEM_BASE;
2634 return;
2635 }
2636 board.membase = simple_strtoul(str, NULL, 16);
2637 last = index;
2638 break;
2639 default:
2640 printk(KERN_ERR "epca: Too many string parms\n");
2641 return;
2642 }
2643 str = temp;
2644 }
2645
2646 if (last < 6) {
2647 printk(KERN_ERR "epca: Insufficient parms specified\n");
2648 return;
2649 }
2650
2651
2652
2653 memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board));
2654
2655 printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n",
2656 num_cards, board_desc[board.type],
2657 board.numports, (int)board.port, (unsigned int) board.membase);
2658 num_cards++;
2659}
2660
2661static int __init epca_real_setup(char *str)
2662{
2663 int ints[11];
2664
2665 epca_setup(get_options(str, 11, ints), ints);
2666 return 1;
2667}
2668
2669__setup("digiepca", epca_real_setup);
2670#endif
2671
2672enum epic_board_types {
2673 brd_xr = 0,
2674 brd_xem,
2675 brd_cx,
2676 brd_xrj,
2677};
2678
2679
2680static struct {
2681 unsigned char board_type;
2682 unsigned bar_idx;
2683} epca_info_tbl[] = {
2684 { PCIXR, 0, },
2685 { PCIXEM, 0, },
2686 { PCICX, 0, },
2687 { PCIXRJ, 2, },
2688};
2689
2690static int __devinit epca_init_one(struct pci_dev *pdev,
2691 const struct pci_device_id *ent)
2692{
2693 static int board_num = -1;
2694 int board_idx, info_idx = ent->driver_data;
2695 unsigned long addr;
2696
2697 if (pci_enable_device(pdev))
2698 return -EIO;
2699
2700 board_num++;
2701 board_idx = board_num + num_cards;
2702 if (board_idx >= MAXBOARDS)
2703 goto err_out;
2704
2705 addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx);
2706 if (!addr) {
2707 printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n",
2708 epca_info_tbl[info_idx].bar_idx);
2709 goto err_out;
2710 }
2711
2712 boards[board_idx].status = ENABLED;
2713 boards[board_idx].type = epca_info_tbl[info_idx].board_type;
2714 boards[board_idx].numports = 0x0;
2715 boards[board_idx].port = addr + PCI_IO_OFFSET;
2716 boards[board_idx].membase = addr;
2717
2718 if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) {
2719 printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
2720 0x200000, addr + PCI_IO_OFFSET);
2721 goto err_out;
2722 }
2723
2724 boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET,
2725 0x200000);
2726 if (!boards[board_idx].re_map_port) {
2727 printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
2728 0x200000, addr + PCI_IO_OFFSET);
2729 goto err_out_free_pciio;
2730 }
2731
2732 if (!request_mem_region(addr, 0x200000, "epca")) {
2733 printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
2734 0x200000, addr);
2735 goto err_out_free_iounmap;
2736 }
2737
2738 boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000);
2739 if (!boards[board_idx].re_map_membase) {
2740 printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
2741 0x200000, addr + PCI_IO_OFFSET);
2742 goto err_out_free_memregion;
2743 }
2744
2745
2746
2747
2748
2749 if (info_idx != brd_xrj) {
2750 pci_write_config_byte(pdev, 0x40, 0);
2751 pci_write_config_byte(pdev, 0x46, 0);
2752 }
2753
2754 return 0;
2755
2756err_out_free_memregion:
2757 release_mem_region(addr, 0x200000);
2758err_out_free_iounmap:
2759 iounmap(boards[board_idx].re_map_port);
2760err_out_free_pciio:
2761 release_mem_region(addr + PCI_IO_OFFSET, 0x200000);
2762err_out:
2763 return -ENODEV;
2764}
2765
2766
2767static struct pci_device_id epca_pci_tbl[] = {
2768 { PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr },
2769 { PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem },
2770 { PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx },
2771 { PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj },
2772 { 0, }
2773};
2774
2775MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
2776
2777static int __init init_PCI(void)
2778{
2779 memset(&epca_driver, 0, sizeof(epca_driver));
2780 epca_driver.name = "epca";
2781 epca_driver.id_table = epca_pci_tbl;
2782 epca_driver.probe = epca_init_one;
2783
2784 return pci_register_driver(&epca_driver);
2785}
2786
2787MODULE_LICENSE("GPL");
2788