1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/tty.h>
25#include <linux/tty_flip.h>
26#include <linux/serial.h>
27#include <linux/seq_file.h>
28#include <linux/cdk.h>
29#include <linux/comstats.h>
30#include <linux/istallion.h>
31#include <linux/ioport.h>
32#include <linux/delay.h>
33#include <linux/init.h>
34#include <linux/device.h>
35#include <linux/wait.h>
36#include <linux/eisa.h>
37#include <linux/ctype.h>
38
39#include <asm/io.h>
40#include <asm/uaccess.h>
41
42#include <linux/pci.h>
43
44
45
46
47
48
49
50
51
52
53#define BRD_UNKNOWN 0
54#define BRD_STALLION 1
55#define BRD_BRUMBY4 2
56#define BRD_ONBOARD2 3
57#define BRD_ONBOARD 4
58#define BRD_ONBOARDE 7
59#define BRD_ECP 23
60#define BRD_ECPE 24
61#define BRD_ECPMC 25
62#define BRD_ECPPCI 29
63
64#define BRD_BRUMBY BRD_BRUMBY4
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105struct stlconf {
106 int brdtype;
107 int ioaddr1;
108 int ioaddr2;
109 unsigned long memaddr;
110 int irq;
111 int irqtype;
112};
113
114static unsigned int stli_nrbrds;
115
116
117static spinlock_t stli_lock;
118static spinlock_t brd_lock;
119
120
121
122
123
124
125#define STLI_EISAPROBE 0
126
127
128
129
130
131
132
133#ifndef STL_SIOMEMMAJOR
134#define STL_SIOMEMMAJOR 28
135#endif
136#ifndef STL_SERIALMAJOR
137#define STL_SERIALMAJOR 24
138#endif
139#ifndef STL_CALLOUTMAJOR
140#define STL_CALLOUTMAJOR 25
141#endif
142
143
144
145
146
147
148
149static char *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver";
150static char *stli_drvname = "istallion";
151static char *stli_drvversion = "5.6.0";
152static char *stli_serialname = "ttyE";
153
154static struct tty_driver *stli_serial;
155static const struct tty_port_operations stli_port_ops;
156
157#define STLI_TXBUFSIZE 4096
158
159
160
161
162
163
164
165
166static char *stli_txcookbuf;
167static int stli_txcooksize;
168static int stli_txcookrealsize;
169static struct tty_struct *stli_txcooktty;
170
171
172
173
174
175
176static struct ktermios stli_deftermios = {
177 .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
178 .c_cc = INIT_C_CC,
179 .c_ispeed = 9600,
180 .c_ospeed = 9600,
181};
182
183
184
185
186
187static comstats_t stli_comstats;
188static combrd_t stli_brdstats;
189static struct asystats stli_cdkstats;
190
191
192
193static DEFINE_MUTEX(stli_brdslock);
194static struct stlibrd *stli_brds[STL_MAXBRDS];
195
196static int stli_shared;
197
198
199
200
201
202
203
204#define BST_FOUND 0x1
205#define BST_STARTED 0x2
206#define BST_PROBED 0x4
207
208
209
210
211
212
213
214#define ST_INITIALIZING 1
215#define ST_OPENING 2
216#define ST_CLOSING 3
217#define ST_CMDING 4
218#define ST_TXBUSY 5
219#define ST_RXING 6
220#define ST_DOFLUSHRX 7
221#define ST_DOFLUSHTX 8
222#define ST_DOSIGS 9
223#define ST_RXSTOP 10
224#define ST_GETSIGS 11
225
226
227
228
229
230static char *stli_brdnames[] = {
231 "Unknown",
232 "Stallion",
233 "Brumby",
234 "ONboard-MC",
235 "ONboard",
236 "Brumby",
237 "Brumby",
238 "ONboard-EI",
239 NULL,
240 "ONboard",
241 "ONboard-MC",
242 "ONboard-MC",
243 NULL,
244 NULL,
245 NULL,
246 NULL,
247 NULL,
248 NULL,
249 NULL,
250 NULL,
251 "EasyIO",
252 "EC8/32-AT",
253 "EC8/32-MC",
254 "EC8/64-AT",
255 "EC8/64-EI",
256 "EC8/64-MC",
257 "EC8/32-PCI",
258 "EC8/64-PCI",
259 "EasyIO-PCI",
260 "EC/RA-PCI",
261};
262
263
264
265
266
267
268
269
270
271static char *board0[8];
272static char *board1[8];
273static char *board2[8];
274static char *board3[8];
275
276static char **stli_brdsp[] = {
277 (char **) &board0,
278 (char **) &board1,
279 (char **) &board2,
280 (char **) &board3
281};
282
283
284
285
286
287
288static struct stlibrdtype {
289 char *name;
290 int type;
291} stli_brdstr[] = {
292 { "stallion", BRD_STALLION },
293 { "1", BRD_STALLION },
294 { "brumby", BRD_BRUMBY },
295 { "brumby4", BRD_BRUMBY },
296 { "brumby/4", BRD_BRUMBY },
297 { "brumby-4", BRD_BRUMBY },
298 { "brumby8", BRD_BRUMBY },
299 { "brumby/8", BRD_BRUMBY },
300 { "brumby-8", BRD_BRUMBY },
301 { "brumby16", BRD_BRUMBY },
302 { "brumby/16", BRD_BRUMBY },
303 { "brumby-16", BRD_BRUMBY },
304 { "2", BRD_BRUMBY },
305 { "onboard2", BRD_ONBOARD2 },
306 { "onboard-2", BRD_ONBOARD2 },
307 { "onboard/2", BRD_ONBOARD2 },
308 { "onboard-mc", BRD_ONBOARD2 },
309 { "onboard/mc", BRD_ONBOARD2 },
310 { "onboard-mca", BRD_ONBOARD2 },
311 { "onboard/mca", BRD_ONBOARD2 },
312 { "3", BRD_ONBOARD2 },
313 { "onboard", BRD_ONBOARD },
314 { "onboardat", BRD_ONBOARD },
315 { "4", BRD_ONBOARD },
316 { "onboarde", BRD_ONBOARDE },
317 { "onboard-e", BRD_ONBOARDE },
318 { "onboard/e", BRD_ONBOARDE },
319 { "onboard-ei", BRD_ONBOARDE },
320 { "onboard/ei", BRD_ONBOARDE },
321 { "7", BRD_ONBOARDE },
322 { "ecp", BRD_ECP },
323 { "ecpat", BRD_ECP },
324 { "ec8/64", BRD_ECP },
325 { "ec8/64-at", BRD_ECP },
326 { "ec8/64-isa", BRD_ECP },
327 { "23", BRD_ECP },
328 { "ecpe", BRD_ECPE },
329 { "ecpei", BRD_ECPE },
330 { "ec8/64-e", BRD_ECPE },
331 { "ec8/64-ei", BRD_ECPE },
332 { "24", BRD_ECPE },
333 { "ecpmc", BRD_ECPMC },
334 { "ec8/64-mc", BRD_ECPMC },
335 { "ec8/64-mca", BRD_ECPMC },
336 { "25", BRD_ECPMC },
337 { "ecppci", BRD_ECPPCI },
338 { "ec/ra", BRD_ECPPCI },
339 { "ec/ra-pc", BRD_ECPPCI },
340 { "ec/ra-pci", BRD_ECPPCI },
341 { "29", BRD_ECPPCI },
342};
343
344
345
346
347MODULE_AUTHOR("Greg Ungerer");
348MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");
349MODULE_LICENSE("GPL");
350
351
352module_param_array(board0, charp, NULL, 0);
353MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");
354module_param_array(board1, charp, NULL, 0);
355MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]");
356module_param_array(board2, charp, NULL, 0);
357MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]");
358module_param_array(board3, charp, NULL, 0);
359MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]");
360
361#if STLI_EISAPROBE != 0
362
363
364
365
366
367
368
369
370static unsigned long stli_eisamemprobeaddrs[] = {
371 0xc0000, 0xd0000, 0xe0000, 0xf0000,
372 0x80000000, 0x80010000, 0x80020000, 0x80030000,
373 0x40000000, 0x40010000, 0x40020000, 0x40030000,
374 0xc0000000, 0xc0010000, 0xc0020000, 0xc0030000,
375 0xff000000, 0xff010000, 0xff020000, 0xff030000,
376};
377
378static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs);
379#endif
380
381
382
383
384#ifndef PCI_DEVICE_ID_ECRA
385#define PCI_DEVICE_ID_ECRA 0x0004
386#endif
387
388static struct pci_device_id istallion_pci_tbl[] = {
389 { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), },
390 { 0 }
391};
392MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
393
394static struct pci_driver stli_pcidriver;
395
396
397
398
399
400
401
402
403#define ECP_IOSIZE 4
404
405#define ECP_MEMSIZE (128 * 1024)
406#define ECP_PCIMEMSIZE (256 * 1024)
407
408#define ECP_ATPAGESIZE (4 * 1024)
409#define ECP_MCPAGESIZE (4 * 1024)
410#define ECP_EIPAGESIZE (64 * 1024)
411#define ECP_PCIPAGESIZE (64 * 1024)
412
413#define STL_EISAID 0x8c4e
414
415
416
417
418#define ECP_ATIREG 0
419#define ECP_ATCONFR 1
420#define ECP_ATMEMAR 2
421#define ECP_ATMEMPR 3
422#define ECP_ATSTOP 0x1
423#define ECP_ATINTENAB 0x10
424#define ECP_ATENABLE 0x20
425#define ECP_ATDISABLE 0x00
426#define ECP_ATADDRMASK 0x3f000
427#define ECP_ATADDRSHFT 12
428
429
430
431
432#define ECP_EIIREG 0
433#define ECP_EIMEMARL 1
434#define ECP_EICONFR 2
435#define ECP_EIMEMARH 3
436#define ECP_EIENABLE 0x1
437#define ECP_EIDISABLE 0x0
438#define ECP_EISTOP 0x4
439#define ECP_EIEDGE 0x00
440#define ECP_EILEVEL 0x80
441#define ECP_EIADDRMASKL 0x00ff0000
442#define ECP_EIADDRSHFTL 16
443#define ECP_EIADDRMASKH 0xff000000
444#define ECP_EIADDRSHFTH 24
445#define ECP_EIBRDENAB 0xc84
446
447#define ECP_EISAID 0x4
448
449
450
451
452
453#define ECP_MCIREG 0
454#define ECP_MCCONFR 1
455#define ECP_MCSTOP 0x20
456#define ECP_MCENABLE 0x80
457#define ECP_MCDISABLE 0x00
458
459
460
461
462
463#define ECP_PCIIREG 0
464#define ECP_PCICONFR 1
465#define ECP_PCISTOP 0x01
466
467
468
469
470
471#define ONB_IOSIZE 16
472#define ONB_MEMSIZE (64 * 1024)
473#define ONB_ATPAGESIZE (64 * 1024)
474#define ONB_MCPAGESIZE (64 * 1024)
475#define ONB_EIMEMSIZE (128 * 1024)
476#define ONB_EIPAGESIZE (64 * 1024)
477
478
479
480
481#define ONB_ATIREG 0
482#define ONB_ATMEMAR 1
483#define ONB_ATCONFR 2
484#define ONB_ATSTOP 0x4
485#define ONB_ATENABLE 0x01
486#define ONB_ATDISABLE 0x00
487#define ONB_ATADDRMASK 0xff0000
488#define ONB_ATADDRSHFT 16
489
490#define ONB_MEMENABLO 0
491#define ONB_MEMENABHI 0x02
492
493
494
495
496#define ONB_EIIREG 0
497#define ONB_EIMEMARL 1
498#define ONB_EICONFR 2
499#define ONB_EIMEMARH 3
500#define ONB_EIENABLE 0x1
501#define ONB_EIDISABLE 0x0
502#define ONB_EISTOP 0x4
503#define ONB_EIEDGE 0x00
504#define ONB_EILEVEL 0x80
505#define ONB_EIADDRMASKL 0x00ff0000
506#define ONB_EIADDRSHFTL 16
507#define ONB_EIADDRMASKH 0xff000000
508#define ONB_EIADDRSHFTH 24
509#define ONB_EIBRDENAB 0xc84
510
511#define ONB_EISAID 0x1
512
513
514
515
516
517#define BBY_IOSIZE 16
518#define BBY_MEMSIZE (64 * 1024)
519#define BBY_PAGESIZE (16 * 1024)
520
521#define BBY_ATIREG 0
522#define BBY_ATCONFR 1
523#define BBY_ATSTOP 0x4
524
525
526
527
528
529#define STAL_IOSIZE 16
530#define STAL_MEMSIZE (64 * 1024)
531#define STAL_PAGESIZE (64 * 1024)
532
533
534
535
536
537
538
539#define ECH_PNLSTATUS 2
540#define ECH_PNL16PORT 0x20
541#define ECH_PNLIDMASK 0x07
542#define ECH_PNLXPID 0x40
543#define ECH_PNLINTRPEND 0x80
544
545
546
547
548
549
550
551
552
553
554#define EBRDINIT(brdp) \
555 if (brdp->init != NULL) \
556 (* brdp->init)(brdp)
557
558#define EBRDENABLE(brdp) \
559 if (brdp->enable != NULL) \
560 (* brdp->enable)(brdp);
561
562#define EBRDDISABLE(brdp) \
563 if (brdp->disable != NULL) \
564 (* brdp->disable)(brdp);
565
566#define EBRDINTR(brdp) \
567 if (brdp->intr != NULL) \
568 (* brdp->intr)(brdp);
569
570#define EBRDRESET(brdp) \
571 if (brdp->reset != NULL) \
572 (* brdp->reset)(brdp);
573
574#define EBRDGETMEMPTR(brdp,offset) \
575 (* brdp->getmemptr)(brdp, offset, __LINE__)
576
577
578
579
580#define STL_MAXBAUD 460800
581#define STL_BAUDBASE 115200
582#define STL_CLOSEDELAY (5 * HZ / 10)
583
584
585
586
587
588
589#define MINOR2BRD(min) (((min) & 0xc0) >> 6)
590#define MINOR2PORT(min) ((min) & 0x3f)
591
592
593
594
595
596
597
598static int stli_parsebrd(struct stlconf *confp, char **argp);
599static int stli_open(struct tty_struct *tty, struct file *filp);
600static void stli_close(struct tty_struct *tty, struct file *filp);
601static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count);
602static int stli_putchar(struct tty_struct *tty, unsigned char ch);
603static void stli_flushchars(struct tty_struct *tty);
604static int stli_writeroom(struct tty_struct *tty);
605static int stli_charsinbuffer(struct tty_struct *tty);
606static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
607static void stli_settermios(struct tty_struct *tty, struct ktermios *old);
608static void stli_throttle(struct tty_struct *tty);
609static void stli_unthrottle(struct tty_struct *tty);
610static void stli_stop(struct tty_struct *tty);
611static void stli_start(struct tty_struct *tty);
612static void stli_flushbuffer(struct tty_struct *tty);
613static int stli_breakctl(struct tty_struct *tty, int state);
614static void stli_waituntilsent(struct tty_struct *tty, int timeout);
615static void stli_sendxchar(struct tty_struct *tty, char ch);
616static void stli_hangup(struct tty_struct *tty);
617
618static int stli_brdinit(struct stlibrd *brdp);
619static int stli_startbrd(struct stlibrd *brdp);
620static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
621static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
622static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
623static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp);
624static void stli_poll(unsigned long arg);
625static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp);
626static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp);
627static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait);
628static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait);
629static int stli_setport(struct tty_struct *tty);
630static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
631static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
632static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
633static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp);
634static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp);
635static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
636static long stli_mktiocm(unsigned long sigvalue);
637static void stli_read(struct stlibrd *brdp, struct stliport *portp);
638static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp);
639static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp);
640static int stli_getbrdstats(combrd_t __user *bp);
641static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp);
642static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp);
643static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp);
644static int stli_getportstruct(struct stliport __user *arg);
645static int stli_getbrdstruct(struct stlibrd __user *arg);
646static struct stlibrd *stli_allocbrd(void);
647
648static void stli_ecpinit(struct stlibrd *brdp);
649static void stli_ecpenable(struct stlibrd *brdp);
650static void stli_ecpdisable(struct stlibrd *brdp);
651static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
652static void stli_ecpreset(struct stlibrd *brdp);
653static void stli_ecpintr(struct stlibrd *brdp);
654static void stli_ecpeiinit(struct stlibrd *brdp);
655static void stli_ecpeienable(struct stlibrd *brdp);
656static void stli_ecpeidisable(struct stlibrd *brdp);
657static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
658static void stli_ecpeireset(struct stlibrd *brdp);
659static void stli_ecpmcenable(struct stlibrd *brdp);
660static void stli_ecpmcdisable(struct stlibrd *brdp);
661static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
662static void stli_ecpmcreset(struct stlibrd *brdp);
663static void stli_ecppciinit(struct stlibrd *brdp);
664static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
665static void stli_ecppcireset(struct stlibrd *brdp);
666
667static void stli_onbinit(struct stlibrd *brdp);
668static void stli_onbenable(struct stlibrd *brdp);
669static void stli_onbdisable(struct stlibrd *brdp);
670static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
671static void stli_onbreset(struct stlibrd *brdp);
672static void stli_onbeinit(struct stlibrd *brdp);
673static void stli_onbeenable(struct stlibrd *brdp);
674static void stli_onbedisable(struct stlibrd *brdp);
675static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
676static void stli_onbereset(struct stlibrd *brdp);
677static void stli_bbyinit(struct stlibrd *brdp);
678static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
679static void stli_bbyreset(struct stlibrd *brdp);
680static void stli_stalinit(struct stlibrd *brdp);
681static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
682static void stli_stalreset(struct stlibrd *brdp);
683
684static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, unsigned int portnr);
685
686static int stli_initecp(struct stlibrd *brdp);
687static int stli_initonb(struct stlibrd *brdp);
688#if STLI_EISAPROBE != 0
689static int stli_eisamemprobe(struct stlibrd *brdp);
690#endif
691static int stli_initports(struct stlibrd *brdp);
692
693
694
695
696
697
698
699
700
701static const struct file_operations stli_fsiomem = {
702 .owner = THIS_MODULE,
703 .read = stli_memread,
704 .write = stli_memwrite,
705 .ioctl = stli_memioctl,
706};
707
708
709
710
711
712
713
714
715
716static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0);
717
718static int stli_timeron;
719
720
721
722
723#define STLI_TIMEOUT (jiffies + 1)
724
725
726
727static struct class *istallion_class;
728
729static void stli_cleanup_ports(struct stlibrd *brdp)
730{
731 struct stliport *portp;
732 unsigned int j;
733 struct tty_struct *tty;
734
735 for (j = 0; j < STL_MAXPORTS; j++) {
736 portp = brdp->ports[j];
737 if (portp != NULL) {
738 tty = tty_port_tty_get(&portp->port);
739 if (tty != NULL) {
740 tty_hangup(tty);
741 tty_kref_put(tty);
742 }
743 kfree(portp);
744 }
745 }
746}
747
748
749
750
751
752
753
754static int stli_parsebrd(struct stlconf *confp, char **argp)
755{
756 unsigned int i;
757 char *sp;
758
759 if (argp[0] == NULL || *argp[0] == 0)
760 return 0;
761
762 for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
763 *sp = tolower(*sp);
764
765 for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) {
766 if (strcmp(stli_brdstr[i].name, argp[0]) == 0)
767 break;
768 }
769 if (i == ARRAY_SIZE(stli_brdstr)) {
770 printk(KERN_WARNING "istallion: unknown board name, %s?\n", argp[0]);
771 return 0;
772 }
773
774 confp->brdtype = stli_brdstr[i].type;
775 if (argp[1] != NULL && *argp[1] != 0)
776 confp->ioaddr1 = simple_strtoul(argp[1], NULL, 0);
777 if (argp[2] != NULL && *argp[2] != 0)
778 confp->memaddr = simple_strtoul(argp[2], NULL, 0);
779 return(1);
780}
781
782
783
784static int stli_open(struct tty_struct *tty, struct file *filp)
785{
786 struct stlibrd *brdp;
787 struct stliport *portp;
788 struct tty_port *port;
789 unsigned int minordev, brdnr, portnr;
790 int rc;
791
792 minordev = tty->index;
793 brdnr = MINOR2BRD(minordev);
794 if (brdnr >= stli_nrbrds)
795 return -ENODEV;
796 brdp = stli_brds[brdnr];
797 if (brdp == NULL)
798 return -ENODEV;
799 if ((brdp->state & BST_STARTED) == 0)
800 return -ENODEV;
801 portnr = MINOR2PORT(minordev);
802 if (portnr > brdp->nrports)
803 return -ENODEV;
804
805 portp = brdp->ports[portnr];
806 if (portp == NULL)
807 return -ENODEV;
808 if (portp->devnr < 1)
809 return -ENODEV;
810 port = &portp->port;
811
812
813
814
815
816
817
818
819
820 tty_port_tty_set(port, tty);
821 tty->driver_data = portp;
822 port->count++;
823
824 wait_event_interruptible(portp->raw_wait,
825 !test_bit(ST_INITIALIZING, &portp->state));
826 if (signal_pending(current))
827 return -ERESTARTSYS;
828
829 if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
830 set_bit(ST_INITIALIZING, &portp->state);
831 if ((rc = stli_initopen(tty, brdp, portp)) >= 0) {
832
833 port->flags |= ASYNC_INITIALIZED;
834 clear_bit(TTY_IO_ERROR, &tty->flags);
835 }
836 clear_bit(ST_INITIALIZING, &portp->state);
837 wake_up_interruptible(&portp->raw_wait);
838 if (rc < 0)
839 return rc;
840 }
841 return tty_port_block_til_ready(&portp->port, tty, filp);
842}
843
844
845
846static void stli_close(struct tty_struct *tty, struct file *filp)
847{
848 struct stlibrd *brdp;
849 struct stliport *portp;
850 struct tty_port *port;
851 unsigned long flags;
852
853 portp = tty->driver_data;
854 if (portp == NULL)
855 return;
856 port = &portp->port;
857
858 if (tty_port_close_start(port, tty, filp) == 0)
859 return;
860
861
862
863
864
865
866
867 spin_lock_irqsave(&stli_lock, flags);
868 if (tty == stli_txcooktty)
869 stli_flushchars(tty);
870 spin_unlock_irqrestore(&stli_lock, flags);
871
872
873
874 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
875 tty_wait_until_sent(tty, portp->closing_wait);
876
877
878 port->flags &= ~ASYNC_INITIALIZED;
879
880 brdp = stli_brds[portp->brdnr];
881 stli_rawclose(brdp, portp, 0, 0);
882 if (tty->termios->c_cflag & HUPCL) {
883 stli_mkasysigs(&portp->asig, 0, 0);
884 if (test_bit(ST_CMDING, &portp->state))
885 set_bit(ST_DOSIGS, &portp->state);
886 else
887 stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig,
888 sizeof(asysigs_t), 0);
889 }
890 clear_bit(ST_TXBUSY, &portp->state);
891 clear_bit(ST_RXSTOP, &portp->state);
892 set_bit(TTY_IO_ERROR, &tty->flags);
893 tty_ldisc_flush(tty);
894 set_bit(ST_DOFLUSHRX, &portp->state);
895 stli_flushbuffer(tty);
896
897 tty_port_close_end(port, tty);
898 tty_port_tty_set(port, NULL);
899}
900
901
902
903
904
905
906
907
908
909
910
911static int stli_initopen(struct tty_struct *tty,
912 struct stlibrd *brdp, struct stliport *portp)
913{
914 asynotify_t nt;
915 asyport_t aport;
916 int rc;
917
918 if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)
919 return rc;
920
921 memset(&nt, 0, sizeof(asynotify_t));
922 nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
923 nt.signal = SG_DCD;
924 if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,
925 sizeof(asynotify_t), 0)) < 0)
926 return rc;
927
928 stli_mkasyport(tty, portp, &aport, tty->termios);
929 if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
930 sizeof(asyport_t), 0)) < 0)
931 return rc;
932
933 set_bit(ST_GETSIGS, &portp->state);
934 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,
935 sizeof(asysigs_t), 1)) < 0)
936 return rc;
937 if (test_and_clear_bit(ST_GETSIGS, &portp->state))
938 portp->sigs = stli_mktiocm(portp->asig.sigvalue);
939 stli_mkasysigs(&portp->asig, 1, 1);
940 if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
941 sizeof(asysigs_t), 0)) < 0)
942 return rc;
943
944 return 0;
945}
946
947
948
949
950
951
952
953
954
955
956static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait)
957{
958 cdkhdr_t __iomem *hdrp;
959 cdkctrl_t __iomem *cp;
960 unsigned char __iomem *bits;
961 unsigned long flags;
962 int rc;
963
964
965
966
967
968
969
970
971
972
973
974 wait_event_interruptible(portp->raw_wait,
975 !test_bit(ST_CLOSING, &portp->state));
976 if (signal_pending(current)) {
977 return -ERESTARTSYS;
978 }
979
980
981
982
983
984
985 spin_lock_irqsave(&brd_lock, flags);
986 EBRDENABLE(brdp);
987 cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
988 writel(arg, &cp->openarg);
989 writeb(1, &cp->open);
990 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
991 bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
992 portp->portidx;
993 writeb(readb(bits) | portp->portbit, bits);
994 EBRDDISABLE(brdp);
995
996 if (wait == 0) {
997 spin_unlock_irqrestore(&brd_lock, flags);
998 return 0;
999 }
1000
1001
1002
1003
1004
1005 rc = 0;
1006 set_bit(ST_OPENING, &portp->state);
1007 spin_unlock_irqrestore(&brd_lock, flags);
1008
1009 wait_event_interruptible(portp->raw_wait,
1010 !test_bit(ST_OPENING, &portp->state));
1011 if (signal_pending(current))
1012 rc = -ERESTARTSYS;
1013
1014 if ((rc == 0) && (portp->rc != 0))
1015 rc = -EIO;
1016 return rc;
1017}
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait)
1028{
1029 cdkhdr_t __iomem *hdrp;
1030 cdkctrl_t __iomem *cp;
1031 unsigned char __iomem *bits;
1032 unsigned long flags;
1033 int rc;
1034
1035
1036
1037
1038
1039 if (wait) {
1040 wait_event_interruptible(portp->raw_wait,
1041 !test_bit(ST_CLOSING, &portp->state));
1042 if (signal_pending(current)) {
1043 return -ERESTARTSYS;
1044 }
1045 }
1046
1047
1048
1049
1050 spin_lock_irqsave(&brd_lock, flags);
1051 EBRDENABLE(brdp);
1052 cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
1053 writel(arg, &cp->closearg);
1054 writeb(1, &cp->close);
1055 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1056 bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
1057 portp->portidx;
1058 writeb(readb(bits) |portp->portbit, bits);
1059 EBRDDISABLE(brdp);
1060
1061 set_bit(ST_CLOSING, &portp->state);
1062 spin_unlock_irqrestore(&brd_lock, flags);
1063
1064 if (wait == 0)
1065 return 0;
1066
1067
1068
1069
1070
1071 rc = 0;
1072 wait_event_interruptible(portp->raw_wait,
1073 !test_bit(ST_CLOSING, &portp->state));
1074 if (signal_pending(current))
1075 rc = -ERESTARTSYS;
1076
1077 if ((rc == 0) && (portp->rc != 0))
1078 rc = -EIO;
1079 return rc;
1080}
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback)
1092{
1093 wait_event_interruptible(portp->raw_wait,
1094 !test_bit(ST_CMDING, &portp->state));
1095 if (signal_pending(current))
1096 return -ERESTARTSYS;
1097
1098 stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
1099
1100 wait_event_interruptible(portp->raw_wait,
1101 !test_bit(ST_CMDING, &portp->state));
1102 if (signal_pending(current))
1103 return -ERESTARTSYS;
1104
1105 if (portp->rc != 0)
1106 return -EIO;
1107 return 0;
1108}
1109
1110
1111
1112
1113
1114
1115
1116
1117static int stli_setport(struct tty_struct *tty)
1118{
1119 struct stliport *portp = tty->driver_data;
1120 struct stlibrd *brdp;
1121 asyport_t aport;
1122
1123 if (portp == NULL)
1124 return -ENODEV;
1125 if (portp->brdnr >= stli_nrbrds)
1126 return -ENODEV;
1127 brdp = stli_brds[portp->brdnr];
1128 if (brdp == NULL)
1129 return -ENODEV;
1130
1131 stli_mkasyport(tty, portp, &aport, tty->termios);
1132 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
1133}
1134
1135
1136
1137static int stli_carrier_raised(struct tty_port *port)
1138{
1139 struct stliport *portp = container_of(port, struct stliport, port);
1140 return (portp->sigs & TIOCM_CD) ? 1 : 0;
1141}
1142
1143static void stli_raise_dtr_rts(struct tty_port *port)
1144{
1145 struct stliport *portp = container_of(port, struct stliport, port);
1146 struct stlibrd *brdp = stli_brds[portp->brdnr];
1147 stli_mkasysigs(&portp->asig, 1, 1);
1148 if (stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1149 sizeof(asysigs_t), 0) < 0)
1150 printk(KERN_WARNING "istallion: dtr raise failed.\n");
1151}
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count)
1163{
1164 cdkasy_t __iomem *ap;
1165 cdkhdr_t __iomem *hdrp;
1166 unsigned char __iomem *bits;
1167 unsigned char __iomem *shbuf;
1168 unsigned char *chbuf;
1169 struct stliport *portp;
1170 struct stlibrd *brdp;
1171 unsigned int len, stlen, head, tail, size;
1172 unsigned long flags;
1173
1174 if (tty == stli_txcooktty)
1175 stli_flushchars(tty);
1176 portp = tty->driver_data;
1177 if (portp == NULL)
1178 return 0;
1179 if (portp->brdnr >= stli_nrbrds)
1180 return 0;
1181 brdp = stli_brds[portp->brdnr];
1182 if (brdp == NULL)
1183 return 0;
1184 chbuf = (unsigned char *) buf;
1185
1186
1187
1188
1189 spin_lock_irqsave(&brd_lock, flags);
1190 EBRDENABLE(brdp);
1191 ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
1192 head = (unsigned int) readw(&ap->txq.head);
1193 tail = (unsigned int) readw(&ap->txq.tail);
1194 if (tail != ((unsigned int) readw(&ap->txq.tail)))
1195 tail = (unsigned int) readw(&ap->txq.tail);
1196 size = portp->txsize;
1197 if (head >= tail) {
1198 len = size - (head - tail) - 1;
1199 stlen = size - head;
1200 } else {
1201 len = tail - head - 1;
1202 stlen = len;
1203 }
1204
1205 len = min(len, (unsigned int)count);
1206 count = 0;
1207 shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset);
1208
1209 while (len > 0) {
1210 stlen = min(len, stlen);
1211 memcpy_toio(shbuf + head, chbuf, stlen);
1212 chbuf += stlen;
1213 len -= stlen;
1214 count += stlen;
1215 head += stlen;
1216 if (head >= size) {
1217 head = 0;
1218 stlen = tail;
1219 }
1220 }
1221
1222 ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
1223 writew(head, &ap->txq.head);
1224 if (test_bit(ST_TXBUSY, &portp->state)) {
1225 if (readl(&ap->changed.data) & DT_TXEMPTY)
1226 writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);
1227 }
1228 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1229 bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
1230 portp->portidx;
1231 writeb(readb(bits) | portp->portbit, bits);
1232 set_bit(ST_TXBUSY, &portp->state);
1233 EBRDDISABLE(brdp);
1234 spin_unlock_irqrestore(&brd_lock, flags);
1235
1236 return(count);
1237}
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249static int stli_putchar(struct tty_struct *tty, unsigned char ch)
1250{
1251 if (tty != stli_txcooktty) {
1252 if (stli_txcooktty != NULL)
1253 stli_flushchars(stli_txcooktty);
1254 stli_txcooktty = tty;
1255 }
1256
1257 stli_txcookbuf[stli_txcooksize++] = ch;
1258 return 0;
1259}
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271static void stli_flushchars(struct tty_struct *tty)
1272{
1273 cdkhdr_t __iomem *hdrp;
1274 unsigned char __iomem *bits;
1275 cdkasy_t __iomem *ap;
1276 struct tty_struct *cooktty;
1277 struct stliport *portp;
1278 struct stlibrd *brdp;
1279 unsigned int len, stlen, head, tail, size, count, cooksize;
1280 unsigned char *buf;
1281 unsigned char __iomem *shbuf;
1282 unsigned long flags;
1283
1284 cooksize = stli_txcooksize;
1285 cooktty = stli_txcooktty;
1286 stli_txcooksize = 0;
1287 stli_txcookrealsize = 0;
1288 stli_txcooktty = NULL;
1289
1290 if (cooktty == NULL)
1291 return;
1292 if (tty != cooktty)
1293 tty = cooktty;
1294 if (cooksize == 0)
1295 return;
1296
1297 portp = tty->driver_data;
1298 if (portp == NULL)
1299 return;
1300 if (portp->brdnr >= stli_nrbrds)
1301 return;
1302 brdp = stli_brds[portp->brdnr];
1303 if (brdp == NULL)
1304 return;
1305
1306 spin_lock_irqsave(&brd_lock, flags);
1307 EBRDENABLE(brdp);
1308
1309 ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
1310 head = (unsigned int) readw(&ap->txq.head);
1311 tail = (unsigned int) readw(&ap->txq.tail);
1312 if (tail != ((unsigned int) readw(&ap->txq.tail)))
1313 tail = (unsigned int) readw(&ap->txq.tail);
1314 size = portp->txsize;
1315 if (head >= tail) {
1316 len = size - (head - tail) - 1;
1317 stlen = size - head;
1318 } else {
1319 len = tail - head - 1;
1320 stlen = len;
1321 }
1322
1323 len = min(len, cooksize);
1324 count = 0;
1325 shbuf = EBRDGETMEMPTR(brdp, portp->txoffset);
1326 buf = stli_txcookbuf;
1327
1328 while (len > 0) {
1329 stlen = min(len, stlen);
1330 memcpy_toio(shbuf + head, buf, stlen);
1331 buf += stlen;
1332 len -= stlen;
1333 count += stlen;
1334 head += stlen;
1335 if (head >= size) {
1336 head = 0;
1337 stlen = tail;
1338 }
1339 }
1340
1341 ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
1342 writew(head, &ap->txq.head);
1343
1344 if (test_bit(ST_TXBUSY, &portp->state)) {
1345 if (readl(&ap->changed.data) & DT_TXEMPTY)
1346 writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);
1347 }
1348 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
1349 bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
1350 portp->portidx;
1351 writeb(readb(bits) | portp->portbit, bits);
1352 set_bit(ST_TXBUSY, &portp->state);
1353
1354 EBRDDISABLE(brdp);
1355 spin_unlock_irqrestore(&brd_lock, flags);
1356}
1357
1358
1359
1360static int stli_writeroom(struct tty_struct *tty)
1361{
1362 cdkasyrq_t __iomem *rp;
1363 struct stliport *portp;
1364 struct stlibrd *brdp;
1365 unsigned int head, tail, len;
1366 unsigned long flags;
1367
1368 if (tty == stli_txcooktty) {
1369 if (stli_txcookrealsize != 0) {
1370 len = stli_txcookrealsize - stli_txcooksize;
1371 return len;
1372 }
1373 }
1374
1375 portp = tty->driver_data;
1376 if (portp == NULL)
1377 return 0;
1378 if (portp->brdnr >= stli_nrbrds)
1379 return 0;
1380 brdp = stli_brds[portp->brdnr];
1381 if (brdp == NULL)
1382 return 0;
1383
1384 spin_lock_irqsave(&brd_lock, flags);
1385 EBRDENABLE(brdp);
1386 rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
1387 head = (unsigned int) readw(&rp->head);
1388 tail = (unsigned int) readw(&rp->tail);
1389 if (tail != ((unsigned int) readw(&rp->tail)))
1390 tail = (unsigned int) readw(&rp->tail);
1391 len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head);
1392 len--;
1393 EBRDDISABLE(brdp);
1394 spin_unlock_irqrestore(&brd_lock, flags);
1395
1396 if (tty == stli_txcooktty) {
1397 stli_txcookrealsize = len;
1398 len -= stli_txcooksize;
1399 }
1400 return len;
1401}
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413static int stli_charsinbuffer(struct tty_struct *tty)
1414{
1415 cdkasyrq_t __iomem *rp;
1416 struct stliport *portp;
1417 struct stlibrd *brdp;
1418 unsigned int head, tail, len;
1419 unsigned long flags;
1420
1421 if (tty == stli_txcooktty)
1422 stli_flushchars(tty);
1423 portp = tty->driver_data;
1424 if (portp == NULL)
1425 return 0;
1426 if (portp->brdnr >= stli_nrbrds)
1427 return 0;
1428 brdp = stli_brds[portp->brdnr];
1429 if (brdp == NULL)
1430 return 0;
1431
1432 spin_lock_irqsave(&brd_lock, flags);
1433 EBRDENABLE(brdp);
1434 rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
1435 head = (unsigned int) readw(&rp->head);
1436 tail = (unsigned int) readw(&rp->tail);
1437 if (tail != ((unsigned int) readw(&rp->tail)))
1438 tail = (unsigned int) readw(&rp->tail);
1439 len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head));
1440 if ((len == 0) && test_bit(ST_TXBUSY, &portp->state))
1441 len = 1;
1442 EBRDDISABLE(brdp);
1443 spin_unlock_irqrestore(&brd_lock, flags);
1444
1445 return len;
1446}
1447
1448
1449
1450
1451
1452
1453
1454static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp)
1455{
1456 struct serial_struct sio;
1457 struct stlibrd *brdp;
1458
1459 memset(&sio, 0, sizeof(struct serial_struct));
1460 sio.type = PORT_UNKNOWN;
1461 sio.line = portp->portnr;
1462 sio.irq = 0;
1463 sio.flags = portp->port.flags;
1464 sio.baud_base = portp->baud_base;
1465 sio.close_delay = portp->port.close_delay;
1466 sio.closing_wait = portp->closing_wait;
1467 sio.custom_divisor = portp->custom_divisor;
1468 sio.xmit_fifo_size = 0;
1469 sio.hub6 = 0;
1470
1471 brdp = stli_brds[portp->brdnr];
1472 if (brdp != NULL)
1473 sio.port = brdp->iobase;
1474
1475 return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ?
1476 -EFAULT : 0;
1477}
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp)
1488{
1489 struct serial_struct sio;
1490 int rc;
1491 struct stliport *portp = tty->driver_data;
1492
1493 if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
1494 return -EFAULT;
1495 if (!capable(CAP_SYS_ADMIN)) {
1496 if ((sio.baud_base != portp->baud_base) ||
1497 (sio.close_delay != portp->port.close_delay) ||
1498 ((sio.flags & ~ASYNC_USR_MASK) !=
1499 (portp->port.flags & ~ASYNC_USR_MASK)))
1500 return -EPERM;
1501 }
1502
1503 portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
1504 (sio.flags & ASYNC_USR_MASK);
1505 portp->baud_base = sio.baud_base;
1506 portp->port.close_delay = sio.close_delay;
1507 portp->closing_wait = sio.closing_wait;
1508 portp->custom_divisor = sio.custom_divisor;
1509
1510 if ((rc = stli_setport(tty)) < 0)
1511 return rc;
1512 return 0;
1513}
1514
1515
1516
1517static int stli_tiocmget(struct tty_struct *tty, struct file *file)
1518{
1519 struct stliport *portp = tty->driver_data;
1520 struct stlibrd *brdp;
1521 int rc;
1522
1523 if (portp == NULL)
1524 return -ENODEV;
1525 if (portp->brdnr >= stli_nrbrds)
1526 return 0;
1527 brdp = stli_brds[portp->brdnr];
1528 if (brdp == NULL)
1529 return 0;
1530 if (tty->flags & (1 << TTY_IO_ERROR))
1531 return -EIO;
1532
1533 if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,
1534 &portp->asig, sizeof(asysigs_t), 1)) < 0)
1535 return rc;
1536
1537 return stli_mktiocm(portp->asig.sigvalue);
1538}
1539
1540static int stli_tiocmset(struct tty_struct *tty, struct file *file,
1541 unsigned int set, unsigned int clear)
1542{
1543 struct stliport *portp = tty->driver_data;
1544 struct stlibrd *brdp;
1545 int rts = -1, dtr = -1;
1546
1547 if (portp == NULL)
1548 return -ENODEV;
1549 if (portp->brdnr >= stli_nrbrds)
1550 return 0;
1551 brdp = stli_brds[portp->brdnr];
1552 if (brdp == NULL)
1553 return 0;
1554 if (tty->flags & (1 << TTY_IO_ERROR))
1555 return -EIO;
1556
1557 if (set & TIOCM_RTS)
1558 rts = 1;
1559 if (set & TIOCM_DTR)
1560 dtr = 1;
1561 if (clear & TIOCM_RTS)
1562 rts = 0;
1563 if (clear & TIOCM_DTR)
1564 dtr = 0;
1565
1566 stli_mkasysigs(&portp->asig, dtr, rts);
1567
1568 return stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1569 sizeof(asysigs_t), 0);
1570}
1571
1572static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1573{
1574 struct stliport *portp;
1575 struct stlibrd *brdp;
1576 int rc;
1577 void __user *argp = (void __user *)arg;
1578
1579 portp = tty->driver_data;
1580 if (portp == NULL)
1581 return -ENODEV;
1582 if (portp->brdnr >= stli_nrbrds)
1583 return 0;
1584 brdp = stli_brds[portp->brdnr];
1585 if (brdp == NULL)
1586 return 0;
1587
1588 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1589 (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
1590 if (tty->flags & (1 << TTY_IO_ERROR))
1591 return -EIO;
1592 }
1593
1594 rc = 0;
1595
1596 switch (cmd) {
1597 case TIOCGSERIAL:
1598 rc = stli_getserial(portp, argp);
1599 break;
1600 case TIOCSSERIAL:
1601 rc = stli_setserial(tty, argp);
1602 break;
1603 case STL_GETPFLAG:
1604 rc = put_user(portp->pflag, (unsigned __user *)argp);
1605 break;
1606 case STL_SETPFLAG:
1607 if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0)
1608 stli_setport(tty);
1609 break;
1610 case COM_GETPORTSTATS:
1611 rc = stli_getportstats(tty, portp, argp);
1612 break;
1613 case COM_CLRPORTSTATS:
1614 rc = stli_clrportstats(portp, argp);
1615 break;
1616 case TIOCSERCONFIG:
1617 case TIOCSERGWILD:
1618 case TIOCSERSWILD:
1619 case TIOCSERGETLSR:
1620 case TIOCSERGSTRUCT:
1621 case TIOCSERGETMULTI:
1622 case TIOCSERSETMULTI:
1623 default:
1624 rc = -ENOIOCTLCMD;
1625 break;
1626 }
1627
1628 return rc;
1629}
1630
1631
1632
1633
1634
1635
1636
1637
1638static void stli_settermios(struct tty_struct *tty, struct ktermios *old)
1639{
1640 struct stliport *portp;
1641 struct stlibrd *brdp;
1642 struct ktermios *tiosp;
1643 asyport_t aport;
1644
1645 portp = tty->driver_data;
1646 if (portp == NULL)
1647 return;
1648 if (portp->brdnr >= stli_nrbrds)
1649 return;
1650 brdp = stli_brds[portp->brdnr];
1651 if (brdp == NULL)
1652 return;
1653
1654 tiosp = tty->termios;
1655
1656 stli_mkasyport(tty, portp, &aport, tiosp);
1657 stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0);
1658 stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1);
1659 stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
1660 sizeof(asysigs_t), 0);
1661 if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0))
1662 tty->hw_stopped = 0;
1663 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
1664 wake_up_interruptible(&portp->port.open_wait);
1665}
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679static void stli_throttle(struct tty_struct *tty)
1680{
1681 struct stliport *portp = tty->driver_data;
1682 if (portp == NULL)
1683 return;
1684 set_bit(ST_RXSTOP, &portp->state);
1685}
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695static void stli_unthrottle(struct tty_struct *tty)
1696{
1697 struct stliport *portp = tty->driver_data;
1698 if (portp == NULL)
1699 return;
1700 clear_bit(ST_RXSTOP, &portp->state);
1701}
1702
1703
1704
1705
1706
1707
1708
1709static void stli_stop(struct tty_struct *tty)
1710{
1711}
1712
1713
1714
1715
1716
1717
1718
1719static void stli_start(struct tty_struct *tty)
1720{
1721}
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732static void stli_hangup(struct tty_struct *tty)
1733{
1734 struct stliport *portp;
1735 struct stlibrd *brdp;
1736 struct tty_port *port;
1737 unsigned long flags;
1738
1739 portp = tty->driver_data;
1740 if (portp == NULL)
1741 return;
1742 if (portp->brdnr >= stli_nrbrds)
1743 return;
1744 brdp = stli_brds[portp->brdnr];
1745 if (brdp == NULL)
1746 return;
1747 port = &portp->port;
1748
1749 spin_lock_irqsave(&port->lock, flags);
1750 port->flags &= ~ASYNC_INITIALIZED;
1751 spin_unlock_irqrestore(&port->lock, flags);
1752
1753 if (!test_bit(ST_CLOSING, &portp->state))
1754 stli_rawclose(brdp, portp, 0, 0);
1755
1756 spin_lock_irqsave(&stli_lock, flags);
1757 if (tty->termios->c_cflag & HUPCL) {
1758 stli_mkasysigs(&portp->asig, 0, 0);
1759 if (test_bit(ST_CMDING, &portp->state)) {
1760 set_bit(ST_DOSIGS, &portp->state);
1761 set_bit(ST_DOFLUSHTX, &portp->state);
1762 set_bit(ST_DOFLUSHRX, &portp->state);
1763 } else {
1764 stli_sendcmd(brdp, portp, A_SETSIGNALSF,
1765 &portp->asig, sizeof(asysigs_t), 0);
1766 }
1767 }
1768
1769 clear_bit(ST_TXBUSY, &portp->state);
1770 clear_bit(ST_RXSTOP, &portp->state);
1771 set_bit(TTY_IO_ERROR, &tty->flags);
1772 spin_unlock_irqrestore(&stli_lock, flags);
1773
1774 tty_port_hangup(port);
1775}
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786static void stli_flushbuffer(struct tty_struct *tty)
1787{
1788 struct stliport *portp;
1789 struct stlibrd *brdp;
1790 unsigned long ftype, flags;
1791
1792 portp = tty->driver_data;
1793 if (portp == NULL)
1794 return;
1795 if (portp->brdnr >= stli_nrbrds)
1796 return;
1797 brdp = stli_brds[portp->brdnr];
1798 if (brdp == NULL)
1799 return;
1800
1801 spin_lock_irqsave(&brd_lock, flags);
1802 if (tty == stli_txcooktty) {
1803 stli_txcooktty = NULL;
1804 stli_txcooksize = 0;
1805 stli_txcookrealsize = 0;
1806 }
1807 if (test_bit(ST_CMDING, &portp->state)) {
1808 set_bit(ST_DOFLUSHTX, &portp->state);
1809 } else {
1810 ftype = FLUSHTX;
1811 if (test_bit(ST_DOFLUSHRX, &portp->state)) {
1812 ftype |= FLUSHRX;
1813 clear_bit(ST_DOFLUSHRX, &portp->state);
1814 }
1815 __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);
1816 }
1817 spin_unlock_irqrestore(&brd_lock, flags);
1818 tty_wakeup(tty);
1819}
1820
1821
1822
1823static int stli_breakctl(struct tty_struct *tty, int state)
1824{
1825 struct stlibrd *brdp;
1826 struct stliport *portp;
1827 long arg;
1828
1829 portp = tty->driver_data;
1830 if (portp == NULL)
1831 return -EINVAL;
1832 if (portp->brdnr >= stli_nrbrds)
1833 return -EINVAL;
1834 brdp = stli_brds[portp->brdnr];
1835 if (brdp == NULL)
1836 return -EINVAL;
1837
1838 arg = (state == -1) ? BREAKON : BREAKOFF;
1839 stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
1840 return 0;
1841}
1842
1843
1844
1845static void stli_waituntilsent(struct tty_struct *tty, int timeout)
1846{
1847 struct stliport *portp;
1848 unsigned long tend;
1849
1850 portp = tty->driver_data;
1851 if (portp == NULL)
1852 return;
1853
1854 if (timeout == 0)
1855 timeout = HZ;
1856 tend = jiffies + timeout;
1857
1858 while (test_bit(ST_TXBUSY, &portp->state)) {
1859 if (signal_pending(current))
1860 break;
1861 msleep_interruptible(20);
1862 if (time_after_eq(jiffies, tend))
1863 break;
1864 }
1865}
1866
1867
1868
1869static void stli_sendxchar(struct tty_struct *tty, char ch)
1870{
1871 struct stlibrd *brdp;
1872 struct stliport *portp;
1873 asyctrl_t actrl;
1874
1875 portp = tty->driver_data;
1876 if (portp == NULL)
1877 return;
1878 if (portp->brdnr >= stli_nrbrds)
1879 return;
1880 brdp = stli_brds[portp->brdnr];
1881 if (brdp == NULL)
1882 return;
1883
1884 memset(&actrl, 0, sizeof(asyctrl_t));
1885 if (ch == STOP_CHAR(tty)) {
1886 actrl.rxctrl = CT_STOPFLOW;
1887 } else if (ch == START_CHAR(tty)) {
1888 actrl.rxctrl = CT_STARTFLOW;
1889 } else {
1890 actrl.txctrl = CT_SENDCHR;
1891 actrl.tximdch = ch;
1892 }
1893 stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
1894}
1895
1896static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr)
1897{
1898 char *uart;
1899 int rc;
1900
1901 rc = stli_portcmdstats(NULL, portp);
1902
1903 uart = "UNKNOWN";
1904 if (brdp->state & BST_STARTED) {
1905 switch (stli_comstats.hwid) {
1906 case 0: uart = "2681"; break;
1907 case 1: uart = "SC26198"; break;
1908 default:uart = "CD1400"; break;
1909 }
1910 }
1911 seq_printf(m, "%d: uart:%s ", portnr, uart);
1912
1913 if ((brdp->state & BST_STARTED) && (rc >= 0)) {
1914 char sep;
1915
1916 seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal,
1917 (int) stli_comstats.rxtotal);
1918
1919 if (stli_comstats.rxframing)
1920 seq_printf(m, " fe:%d",
1921 (int) stli_comstats.rxframing);
1922 if (stli_comstats.rxparity)
1923 seq_printf(m, " pe:%d",
1924 (int) stli_comstats.rxparity);
1925 if (stli_comstats.rxbreaks)
1926 seq_printf(m, " brk:%d",
1927 (int) stli_comstats.rxbreaks);
1928 if (stli_comstats.rxoverrun)
1929 seq_printf(m, " oe:%d",
1930 (int) stli_comstats.rxoverrun);
1931
1932 sep = ' ';
1933 if (stli_comstats.signals & TIOCM_RTS) {
1934 seq_printf(m, "%c%s", sep, "RTS");
1935 sep = '|';
1936 }
1937 if (stli_comstats.signals & TIOCM_CTS) {
1938 seq_printf(m, "%c%s", sep, "CTS");
1939 sep = '|';
1940 }
1941 if (stli_comstats.signals & TIOCM_DTR) {
1942 seq_printf(m, "%c%s", sep, "DTR");
1943 sep = '|';
1944 }
1945 if (stli_comstats.signals & TIOCM_CD) {
1946 seq_printf(m, "%c%s", sep, "DCD");
1947 sep = '|';
1948 }
1949 if (stli_comstats.signals & TIOCM_DSR) {
1950 seq_printf(m, "%c%s", sep, "DSR");
1951 sep = '|';
1952 }
1953 }
1954 seq_putc(m, '\n');
1955}
1956
1957
1958
1959
1960
1961
1962
1963static int stli_proc_show(struct seq_file *m, void *v)
1964{
1965 struct stlibrd *brdp;
1966 struct stliport *portp;
1967 unsigned int brdnr, portnr, totalport;
1968
1969 totalport = 0;
1970
1971 seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion);
1972
1973
1974
1975
1976
1977 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
1978 brdp = stli_brds[brdnr];
1979 if (brdp == NULL)
1980 continue;
1981 if (brdp->state == 0)
1982 continue;
1983
1984 totalport = brdnr * STL_MAXPORTS;
1985 for (portnr = 0; (portnr < brdp->nrports); portnr++,
1986 totalport++) {
1987 portp = brdp->ports[portnr];
1988 if (portp == NULL)
1989 continue;
1990 stli_portinfo(m, brdp, portp, totalport);
1991 }
1992 }
1993 return 0;
1994}
1995
1996static int stli_proc_open(struct inode *inode, struct file *file)
1997{
1998 return single_open(file, stli_proc_show, NULL);
1999}
2000
2001static const struct file_operations stli_proc_fops = {
2002 .owner = THIS_MODULE,
2003 .open = stli_proc_open,
2004 .read = seq_read,
2005 .llseek = seq_lseek,
2006 .release = single_release,
2007};
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback)
2025{
2026 cdkhdr_t __iomem *hdrp;
2027 cdkctrl_t __iomem *cp;
2028 unsigned char __iomem *bits;
2029
2030 if (test_bit(ST_CMDING, &portp->state)) {
2031 printk(KERN_ERR "istallion: command already busy, cmd=%x!\n",
2032 (int) cmd);
2033 return;
2034 }
2035
2036 EBRDENABLE(brdp);
2037 cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
2038 if (size > 0) {
2039 memcpy_toio((void __iomem *) &(cp->args[0]), arg, size);
2040 if (copyback) {
2041 portp->argp = arg;
2042 portp->argsize = size;
2043 }
2044 }
2045 writel(0, &cp->status);
2046 writel(cmd, &cp->cmd);
2047 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2048 bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
2049 portp->portidx;
2050 writeb(readb(bits) | portp->portbit, bits);
2051 set_bit(ST_CMDING, &portp->state);
2052 EBRDDISABLE(brdp);
2053}
2054
2055static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback)
2056{
2057 unsigned long flags;
2058
2059 spin_lock_irqsave(&brd_lock, flags);
2060 __stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
2061 spin_unlock_irqrestore(&brd_lock, flags);
2062}
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074static void stli_read(struct stlibrd *brdp, struct stliport *portp)
2075{
2076 cdkasyrq_t __iomem *rp;
2077 char __iomem *shbuf;
2078 struct tty_struct *tty;
2079 unsigned int head, tail, size;
2080 unsigned int len, stlen;
2081
2082 if (test_bit(ST_RXSTOP, &portp->state))
2083 return;
2084 tty = tty_port_tty_get(&portp->port);
2085 if (tty == NULL)
2086 return;
2087
2088 rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
2089 head = (unsigned int) readw(&rp->head);
2090 if (head != ((unsigned int) readw(&rp->head)))
2091 head = (unsigned int) readw(&rp->head);
2092 tail = (unsigned int) readw(&rp->tail);
2093 size = portp->rxsize;
2094 if (head >= tail) {
2095 len = head - tail;
2096 stlen = len;
2097 } else {
2098 len = size - (tail - head);
2099 stlen = size - tail;
2100 }
2101
2102 len = tty_buffer_request_room(tty, len);
2103
2104 shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset);
2105
2106 while (len > 0) {
2107 unsigned char *cptr;
2108
2109 stlen = min(len, stlen);
2110 tty_prepare_flip_string(tty, &cptr, stlen);
2111 memcpy_fromio(cptr, shbuf + tail, stlen);
2112 len -= stlen;
2113 tail += stlen;
2114 if (tail >= size) {
2115 tail = 0;
2116 stlen = head;
2117 }
2118 }
2119 rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
2120 writew(tail, &rp->tail);
2121
2122 if (head != tail)
2123 set_bit(ST_RXING, &portp->state);
2124
2125 tty_schedule_flip(tty);
2126 tty_kref_put(tty);
2127}
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp)
2138{
2139 int cmd;
2140
2141 if (test_bit(ST_DOSIGS, &portp->state)) {
2142 if (test_bit(ST_DOFLUSHTX, &portp->state) &&
2143 test_bit(ST_DOFLUSHRX, &portp->state))
2144 cmd = A_SETSIGNALSF;
2145 else if (test_bit(ST_DOFLUSHTX, &portp->state))
2146 cmd = A_SETSIGNALSFTX;
2147 else if (test_bit(ST_DOFLUSHRX, &portp->state))
2148 cmd = A_SETSIGNALSFRX;
2149 else
2150 cmd = A_SETSIGNALS;
2151 clear_bit(ST_DOFLUSHTX, &portp->state);
2152 clear_bit(ST_DOFLUSHRX, &portp->state);
2153 clear_bit(ST_DOSIGS, &portp->state);
2154 memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig,
2155 sizeof(asysigs_t));
2156 writel(0, &cp->status);
2157 writel(cmd, &cp->cmd);
2158 set_bit(ST_CMDING, &portp->state);
2159 } else if (test_bit(ST_DOFLUSHTX, &portp->state) ||
2160 test_bit(ST_DOFLUSHRX, &portp->state)) {
2161 cmd = ((test_bit(ST_DOFLUSHTX, &portp->state)) ? FLUSHTX : 0);
2162 cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);
2163 clear_bit(ST_DOFLUSHTX, &portp->state);
2164 clear_bit(ST_DOFLUSHRX, &portp->state);
2165 memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int));
2166 writel(0, &cp->status);
2167 writel(A_FLUSH, &cp->cmd);
2168 set_bit(ST_CMDING, &portp->state);
2169 }
2170}
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
2186{
2187 cdkasy_t __iomem *ap;
2188 cdkctrl_t __iomem *cp;
2189 struct tty_struct *tty;
2190 asynotify_t nt;
2191 unsigned long oldsigs;
2192 int rc, donerx;
2193
2194 ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
2195 cp = &ap->ctrl;
2196
2197
2198
2199
2200 if (test_bit(ST_OPENING, &portp->state)) {
2201 rc = readl(&cp->openarg);
2202 if (readb(&cp->open) == 0 && rc != 0) {
2203 if (rc > 0)
2204 rc--;
2205 writel(0, &cp->openarg);
2206 portp->rc = rc;
2207 clear_bit(ST_OPENING, &portp->state);
2208 wake_up_interruptible(&portp->raw_wait);
2209 }
2210 }
2211
2212
2213
2214
2215 if (test_bit(ST_CLOSING, &portp->state)) {
2216 rc = (int) readl(&cp->closearg);
2217 if (readb(&cp->close) == 0 && rc != 0) {
2218 if (rc > 0)
2219 rc--;
2220 writel(0, &cp->closearg);
2221 portp->rc = rc;
2222 clear_bit(ST_CLOSING, &portp->state);
2223 wake_up_interruptible(&portp->raw_wait);
2224 }
2225 }
2226
2227
2228
2229
2230
2231 if (test_bit(ST_CMDING, &portp->state)) {
2232 rc = readl(&cp->status);
2233 if (readl(&cp->cmd) == 0 && rc != 0) {
2234 if (rc > 0)
2235 rc--;
2236 if (portp->argp != NULL) {
2237 memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]),
2238 portp->argsize);
2239 portp->argp = NULL;
2240 }
2241 writel(0, &cp->status);
2242 portp->rc = rc;
2243 clear_bit(ST_CMDING, &portp->state);
2244 stli_dodelaycmd(portp, cp);
2245 wake_up_interruptible(&portp->raw_wait);
2246 }
2247 }
2248
2249
2250
2251
2252
2253
2254 donerx = 0;
2255
2256 if (ap->notify) {
2257 nt = ap->changed;
2258 ap->notify = 0;
2259 tty = tty_port_tty_get(&portp->port);
2260
2261 if (nt.signal & SG_DCD) {
2262 oldsigs = portp->sigs;
2263 portp->sigs = stli_mktiocm(nt.sigvalue);
2264 clear_bit(ST_GETSIGS, &portp->state);
2265 if ((portp->sigs & TIOCM_CD) &&
2266 ((oldsigs & TIOCM_CD) == 0))
2267 wake_up_interruptible(&portp->port.open_wait);
2268 if ((oldsigs & TIOCM_CD) &&
2269 ((portp->sigs & TIOCM_CD) == 0)) {
2270 if (portp->port.flags & ASYNC_CHECK_CD) {
2271 if (tty)
2272 tty_hangup(tty);
2273 }
2274 }
2275 }
2276
2277 if (nt.data & DT_TXEMPTY)
2278 clear_bit(ST_TXBUSY, &portp->state);
2279 if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
2280 if (tty != NULL) {
2281 tty_wakeup(tty);
2282 EBRDENABLE(brdp);
2283 }
2284 }
2285
2286 if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
2287 if (tty != NULL) {
2288 tty_insert_flip_char(tty, 0, TTY_BREAK);
2289 if (portp->port.flags & ASYNC_SAK) {
2290 do_SAK(tty);
2291 EBRDENABLE(brdp);
2292 }
2293 tty_schedule_flip(tty);
2294 }
2295 }
2296 tty_kref_put(tty);
2297
2298 if (nt.data & DT_RXBUSY) {
2299 donerx++;
2300 stli_read(brdp, portp);
2301 }
2302 }
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312 if ((!donerx) && test_bit(ST_RXING, &portp->state)) {
2313 clear_bit(ST_RXING, &portp->state);
2314 stli_read(brdp, portp);
2315 }
2316
2317 return((test_bit(ST_OPENING, &portp->state) ||
2318 test_bit(ST_CLOSING, &portp->state) ||
2319 test_bit(ST_CMDING, &portp->state) ||
2320 test_bit(ST_TXBUSY, &portp->state) ||
2321 test_bit(ST_RXING, &portp->state)) ? 0 : 1);
2322}
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp)
2333{
2334 struct stliport *portp;
2335 unsigned char hostbits[(STL_MAXCHANS / 8) + 1];
2336 unsigned char slavebits[(STL_MAXCHANS / 8) + 1];
2337 unsigned char __iomem *slavep;
2338 int bitpos, bitat, bitsize;
2339 int channr, nrdevs, slavebitchange;
2340
2341 bitsize = brdp->bitsize;
2342 nrdevs = brdp->nrdevs;
2343
2344
2345
2346
2347
2348
2349
2350
2351 memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset),
2352 bitsize);
2353
2354 memset(&slavebits[0], 0, bitsize);
2355 slavebitchange = 0;
2356
2357 for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2358 if (hostbits[bitpos] == 0)
2359 continue;
2360 channr = bitpos * 8;
2361 for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
2362 if (hostbits[bitpos] & bitat) {
2363 portp = brdp->ports[(channr - 1)];
2364 if (stli_hostcmd(brdp, portp)) {
2365 slavebitchange++;
2366 slavebits[bitpos] |= bitat;
2367 }
2368 }
2369 }
2370 }
2371
2372
2373
2374
2375
2376
2377 if (slavebitchange) {
2378 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2379 slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset;
2380 for (bitpos = 0; (bitpos < bitsize); bitpos++) {
2381 if (readb(slavebits + bitpos))
2382 writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos);
2383 }
2384 }
2385}
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398static void stli_poll(unsigned long arg)
2399{
2400 cdkhdr_t __iomem *hdrp;
2401 struct stlibrd *brdp;
2402 unsigned int brdnr;
2403
2404 mod_timer(&stli_timerlist, STLI_TIMEOUT);
2405
2406
2407
2408
2409 for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
2410 brdp = stli_brds[brdnr];
2411 if (brdp == NULL)
2412 continue;
2413 if ((brdp->state & BST_STARTED) == 0)
2414 continue;
2415
2416 spin_lock(&brd_lock);
2417 EBRDENABLE(brdp);
2418 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
2419 if (readb(&hdrp->hostreq))
2420 stli_brdpoll(brdp, hdrp);
2421 EBRDDISABLE(brdp);
2422 spin_unlock(&brd_lock);
2423 }
2424}
2425
2426
2427
2428
2429
2430
2431
2432
2433static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp,
2434 asyport_t *pp, struct ktermios *tiosp)
2435{
2436 memset(pp, 0, sizeof(asyport_t));
2437
2438
2439
2440
2441 pp->baudout = tty_get_baud_rate(tty);
2442 if ((tiosp->c_cflag & CBAUD) == B38400) {
2443 if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2444 pp->baudout = 57600;
2445 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
2446 pp->baudout = 115200;
2447 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
2448 pp->baudout = 230400;
2449 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
2450 pp->baudout = 460800;
2451 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
2452 pp->baudout = (portp->baud_base / portp->custom_divisor);
2453 }
2454 if (pp->baudout > STL_MAXBAUD)
2455 pp->baudout = STL_MAXBAUD;
2456 pp->baudin = pp->baudout;
2457
2458 switch (tiosp->c_cflag & CSIZE) {
2459 case CS5:
2460 pp->csize = 5;
2461 break;
2462 case CS6:
2463 pp->csize = 6;
2464 break;
2465 case CS7:
2466 pp->csize = 7;
2467 break;
2468 default:
2469 pp->csize = 8;
2470 break;
2471 }
2472
2473 if (tiosp->c_cflag & CSTOPB)
2474 pp->stopbs = PT_STOP2;
2475 else
2476 pp->stopbs = PT_STOP1;
2477
2478 if (tiosp->c_cflag & PARENB) {
2479 if (tiosp->c_cflag & PARODD)
2480 pp->parity = PT_ODDPARITY;
2481 else
2482 pp->parity = PT_EVENPARITY;
2483 } else {
2484 pp->parity = PT_NOPARITY;
2485 }
2486
2487
2488
2489
2490 if (tiosp->c_iflag & IXON) {
2491 pp->flow |= F_IXON;
2492 if (tiosp->c_iflag & IXANY)
2493 pp->flow |= F_IXANY;
2494 }
2495 if (tiosp->c_cflag & CRTSCTS)
2496 pp->flow |= (F_RTSFLOW | F_CTSFLOW);
2497
2498 pp->startin = tiosp->c_cc[VSTART];
2499 pp->stopin = tiosp->c_cc[VSTOP];
2500 pp->startout = tiosp->c_cc[VSTART];
2501 pp->stopout = tiosp->c_cc[VSTOP];
2502
2503
2504
2505
2506
2507
2508
2509 if (tiosp->c_iflag & IGNPAR)
2510 pp->iflag |= FI_IGNRXERRS;
2511 if (tiosp->c_iflag & IGNBRK)
2512 pp->iflag |= FI_IGNBREAK;
2513
2514 portp->rxmarkmsk = 0;
2515 if (tiosp->c_iflag & (INPCK | PARMRK))
2516 pp->iflag |= FI_1MARKRXERRS;
2517 if (tiosp->c_iflag & BRKINT)
2518 portp->rxmarkmsk |= BRKINT;
2519
2520
2521
2522
2523 if (tiosp->c_cflag & CLOCAL)
2524 portp->port.flags &= ~ASYNC_CHECK_CD;
2525 else
2526 portp->port.flags |= ASYNC_CHECK_CD;
2527
2528
2529
2530
2531 pp->pflag = (portp->pflag & 0xffff);
2532 pp->vmin = (portp->pflag & P_RXIMIN) ? 1 : 0;
2533 pp->vtime = (portp->pflag & P_RXITIME) ? 1 : 0;
2534 pp->cc[1] = (portp->pflag & P_RXTHOLD) ? 1 : 0;
2535}
2536
2537
2538
2539
2540
2541
2542
2543
2544static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)
2545{
2546 memset(sp, 0, sizeof(asysigs_t));
2547 if (dtr >= 0) {
2548 sp->signal |= SG_DTR;
2549 sp->sigvalue |= ((dtr > 0) ? SG_DTR : 0);
2550 }
2551 if (rts >= 0) {
2552 sp->signal |= SG_RTS;
2553 sp->sigvalue |= ((rts > 0) ? SG_RTS : 0);
2554 }
2555}
2556
2557
2558
2559
2560
2561
2562
2563
2564static long stli_mktiocm(unsigned long sigvalue)
2565{
2566 long tiocm = 0;
2567 tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);
2568 tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);
2569 tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);
2570 tiocm |= ((sigvalue & SG_DSR) ? TIOCM_DSR : 0);
2571 tiocm |= ((sigvalue & SG_DTR) ? TIOCM_DTR : 0);
2572 tiocm |= ((sigvalue & SG_RTS) ? TIOCM_RTS : 0);
2573 return(tiocm);
2574}
2575
2576
2577
2578
2579
2580
2581
2582
2583static int stli_initports(struct stlibrd *brdp)
2584{
2585 struct stliport *portp;
2586 unsigned int i, panelnr, panelport;
2587
2588 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
2589 portp = kzalloc(sizeof(struct stliport), GFP_KERNEL);
2590 if (!portp) {
2591 printk(KERN_WARNING "istallion: failed to allocate port structure\n");
2592 continue;
2593 }
2594 tty_port_init(&portp->port);
2595 portp->port.ops = &stli_port_ops;
2596 portp->magic = STLI_PORTMAGIC;
2597 portp->portnr = i;
2598 portp->brdnr = brdp->brdnr;
2599 portp->panelnr = panelnr;
2600 portp->baud_base = STL_BAUDBASE;
2601 portp->port.close_delay = STL_CLOSEDELAY;
2602 portp->closing_wait = 30 * HZ;
2603 init_waitqueue_head(&portp->port.open_wait);
2604 init_waitqueue_head(&portp->port.close_wait);
2605 init_waitqueue_head(&portp->raw_wait);
2606 panelport++;
2607 if (panelport >= brdp->panels[panelnr]) {
2608 panelport = 0;
2609 panelnr++;
2610 }
2611 brdp->ports[i] = portp;
2612 }
2613
2614 return 0;
2615}
2616
2617
2618
2619
2620
2621
2622
2623static void stli_ecpinit(struct stlibrd *brdp)
2624{
2625 unsigned long memconf;
2626
2627 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
2628 udelay(10);
2629 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
2630 udelay(100);
2631
2632 memconf = (brdp->memaddr & ECP_ATADDRMASK) >> ECP_ATADDRSHFT;
2633 outb(memconf, (brdp->iobase + ECP_ATMEMAR));
2634}
2635
2636
2637
2638static void stli_ecpenable(struct stlibrd *brdp)
2639{
2640 outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR));
2641}
2642
2643
2644
2645static void stli_ecpdisable(struct stlibrd *brdp)
2646{
2647 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
2648}
2649
2650
2651
2652static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
2653{
2654 void __iomem *ptr;
2655 unsigned char val;
2656
2657 if (offset > brdp->memsize) {
2658 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2659 "range at line=%d(%d), brd=%d\n",
2660 (int) offset, line, __LINE__, brdp->brdnr);
2661 ptr = NULL;
2662 val = 0;
2663 } else {
2664 ptr = brdp->membase + (offset % ECP_ATPAGESIZE);
2665 val = (unsigned char) (offset / ECP_ATPAGESIZE);
2666 }
2667 outb(val, (brdp->iobase + ECP_ATMEMPR));
2668 return(ptr);
2669}
2670
2671
2672
2673static void stli_ecpreset(struct stlibrd *brdp)
2674{
2675 outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
2676 udelay(10);
2677 outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
2678 udelay(500);
2679}
2680
2681
2682
2683static void stli_ecpintr(struct stlibrd *brdp)
2684{
2685 outb(0x1, brdp->iobase);
2686}
2687
2688
2689
2690
2691
2692
2693
2694static void stli_ecpeiinit(struct stlibrd *brdp)
2695{
2696 unsigned long memconf;
2697
2698 outb(0x1, (brdp->iobase + ECP_EIBRDENAB));
2699 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
2700 udelay(10);
2701 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
2702 udelay(500);
2703
2704 memconf = (brdp->memaddr & ECP_EIADDRMASKL) >> ECP_EIADDRSHFTL;
2705 outb(memconf, (brdp->iobase + ECP_EIMEMARL));
2706 memconf = (brdp->memaddr & ECP_EIADDRMASKH) >> ECP_EIADDRSHFTH;
2707 outb(memconf, (brdp->iobase + ECP_EIMEMARH));
2708}
2709
2710
2711
2712static void stli_ecpeienable(struct stlibrd *brdp)
2713{
2714 outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR));
2715}
2716
2717
2718
2719static void stli_ecpeidisable(struct stlibrd *brdp)
2720{
2721 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
2722}
2723
2724
2725
2726static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
2727{
2728 void __iomem *ptr;
2729 unsigned char val;
2730
2731 if (offset > brdp->memsize) {
2732 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2733 "range at line=%d(%d), brd=%d\n",
2734 (int) offset, line, __LINE__, brdp->brdnr);
2735 ptr = NULL;
2736 val = 0;
2737 } else {
2738 ptr = brdp->membase + (offset % ECP_EIPAGESIZE);
2739 if (offset < ECP_EIPAGESIZE)
2740 val = ECP_EIENABLE;
2741 else
2742 val = ECP_EIENABLE | 0x40;
2743 }
2744 outb(val, (brdp->iobase + ECP_EICONFR));
2745 return(ptr);
2746}
2747
2748
2749
2750static void stli_ecpeireset(struct stlibrd *brdp)
2751{
2752 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
2753 udelay(10);
2754 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
2755 udelay(500);
2756}
2757
2758
2759
2760
2761
2762
2763
2764static void stli_ecpmcenable(struct stlibrd *brdp)
2765{
2766 outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR));
2767}
2768
2769
2770
2771static void stli_ecpmcdisable(struct stlibrd *brdp)
2772{
2773 outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR));
2774}
2775
2776
2777
2778static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
2779{
2780 void __iomem *ptr;
2781 unsigned char val;
2782
2783 if (offset > brdp->memsize) {
2784 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2785 "range at line=%d(%d), brd=%d\n",
2786 (int) offset, line, __LINE__, brdp->brdnr);
2787 ptr = NULL;
2788 val = 0;
2789 } else {
2790 ptr = brdp->membase + (offset % ECP_MCPAGESIZE);
2791 val = ((unsigned char) (offset / ECP_MCPAGESIZE)) | ECP_MCENABLE;
2792 }
2793 outb(val, (brdp->iobase + ECP_MCCONFR));
2794 return(ptr);
2795}
2796
2797
2798
2799static void stli_ecpmcreset(struct stlibrd *brdp)
2800{
2801 outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR));
2802 udelay(10);
2803 outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR));
2804 udelay(500);
2805}
2806
2807
2808
2809
2810
2811
2812
2813static void stli_ecppciinit(struct stlibrd *brdp)
2814{
2815 outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
2816 udelay(10);
2817 outb(0, (brdp->iobase + ECP_PCICONFR));
2818 udelay(500);
2819}
2820
2821
2822
2823static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
2824{
2825 void __iomem *ptr;
2826 unsigned char val;
2827
2828 if (offset > brdp->memsize) {
2829 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2830 "range at line=%d(%d), board=%d\n",
2831 (int) offset, line, __LINE__, brdp->brdnr);
2832 ptr = NULL;
2833 val = 0;
2834 } else {
2835 ptr = brdp->membase + (offset % ECP_PCIPAGESIZE);
2836 val = (offset / ECP_PCIPAGESIZE) << 1;
2837 }
2838 outb(val, (brdp->iobase + ECP_PCICONFR));
2839 return(ptr);
2840}
2841
2842
2843
2844static void stli_ecppcireset(struct stlibrd *brdp)
2845{
2846 outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
2847 udelay(10);
2848 outb(0, (brdp->iobase + ECP_PCICONFR));
2849 udelay(500);
2850}
2851
2852
2853
2854
2855
2856
2857
2858static void stli_onbinit(struct stlibrd *brdp)
2859{
2860 unsigned long memconf;
2861
2862 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
2863 udelay(10);
2864 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
2865 mdelay(1000);
2866
2867 memconf = (brdp->memaddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT;
2868 outb(memconf, (brdp->iobase + ONB_ATMEMAR));
2869 outb(0x1, brdp->iobase);
2870 mdelay(1);
2871}
2872
2873
2874
2875static void stli_onbenable(struct stlibrd *brdp)
2876{
2877 outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR));
2878}
2879
2880
2881
2882static void stli_onbdisable(struct stlibrd *brdp)
2883{
2884 outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR));
2885}
2886
2887
2888
2889static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
2890{
2891 void __iomem *ptr;
2892
2893 if (offset > brdp->memsize) {
2894 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2895 "range at line=%d(%d), brd=%d\n",
2896 (int) offset, line, __LINE__, brdp->brdnr);
2897 ptr = NULL;
2898 } else {
2899 ptr = brdp->membase + (offset % ONB_ATPAGESIZE);
2900 }
2901 return(ptr);
2902}
2903
2904
2905
2906static void stli_onbreset(struct stlibrd *brdp)
2907{
2908 outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
2909 udelay(10);
2910 outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
2911 mdelay(1000);
2912}
2913
2914
2915
2916
2917
2918
2919
2920static void stli_onbeinit(struct stlibrd *brdp)
2921{
2922 unsigned long memconf;
2923
2924 outb(0x1, (brdp->iobase + ONB_EIBRDENAB));
2925 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
2926 udelay(10);
2927 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
2928 mdelay(1000);
2929
2930 memconf = (brdp->memaddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL;
2931 outb(memconf, (brdp->iobase + ONB_EIMEMARL));
2932 memconf = (brdp->memaddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH;
2933 outb(memconf, (brdp->iobase + ONB_EIMEMARH));
2934 outb(0x1, brdp->iobase);
2935 mdelay(1);
2936}
2937
2938
2939
2940static void stli_onbeenable(struct stlibrd *brdp)
2941{
2942 outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR));
2943}
2944
2945
2946
2947static void stli_onbedisable(struct stlibrd *brdp)
2948{
2949 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
2950}
2951
2952
2953
2954static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
2955{
2956 void __iomem *ptr;
2957 unsigned char val;
2958
2959 if (offset > brdp->memsize) {
2960 printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2961 "range at line=%d(%d), brd=%d\n",
2962 (int) offset, line, __LINE__, brdp->brdnr);
2963 ptr = NULL;
2964 val = 0;
2965 } else {
2966 ptr = brdp->membase + (offset % ONB_EIPAGESIZE);
2967 if (offset < ONB_EIPAGESIZE)
2968 val = ONB_EIENABLE;
2969 else
2970 val = ONB_EIENABLE | 0x40;
2971 }
2972 outb(val, (brdp->iobase + ONB_EICONFR));
2973 return(ptr);
2974}
2975
2976
2977
2978static void stli_onbereset(struct stlibrd *brdp)
2979{
2980 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
2981 udelay(10);
2982 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
2983 mdelay(1000);
2984}
2985
2986
2987
2988
2989
2990
2991
2992static void stli_bbyinit(struct stlibrd *brdp)
2993{
2994 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
2995 udelay(10);
2996 outb(0, (brdp->iobase + BBY_ATCONFR));
2997 mdelay(1000);
2998 outb(0x1, brdp->iobase);
2999 mdelay(1);
3000}
3001
3002
3003
3004static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
3005{
3006 void __iomem *ptr;
3007 unsigned char val;
3008
3009 BUG_ON(offset > brdp->memsize);
3010
3011 ptr = brdp->membase + (offset % BBY_PAGESIZE);
3012 val = (unsigned char) (offset / BBY_PAGESIZE);
3013 outb(val, (brdp->iobase + BBY_ATCONFR));
3014 return(ptr);
3015}
3016
3017
3018
3019static void stli_bbyreset(struct stlibrd *brdp)
3020{
3021 outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
3022 udelay(10);
3023 outb(0, (brdp->iobase + BBY_ATCONFR));
3024 mdelay(1000);
3025}
3026
3027
3028
3029
3030
3031
3032
3033static void stli_stalinit(struct stlibrd *brdp)
3034{
3035 outb(0x1, brdp->iobase);
3036 mdelay(1000);
3037}
3038
3039
3040
3041static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
3042{
3043 BUG_ON(offset > brdp->memsize);
3044 return brdp->membase + (offset % STAL_PAGESIZE);
3045}
3046
3047
3048
3049static void stli_stalreset(struct stlibrd *brdp)
3050{
3051 u32 __iomem *vecp;
3052
3053 vecp = (u32 __iomem *) (brdp->membase + 0x30);
3054 writel(0xffff0000, vecp);
3055 outb(0, brdp->iobase);
3056 mdelay(1000);
3057}
3058
3059
3060
3061
3062
3063
3064
3065
3066static int stli_initecp(struct stlibrd *brdp)
3067{
3068 cdkecpsig_t sig;
3069 cdkecpsig_t __iomem *sigsp;
3070 unsigned int status, nxtid;
3071 char *name;
3072 int retval, panelnr, nrports;
3073
3074 if ((brdp->iobase == 0) || (brdp->memaddr == 0)) {
3075 retval = -ENODEV;
3076 goto err;
3077 }
3078
3079 brdp->iosize = ECP_IOSIZE;
3080
3081 if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
3082 retval = -EIO;
3083 goto err;
3084 }
3085
3086
3087
3088
3089
3090
3091 switch (brdp->brdtype) {
3092 case BRD_ECP:
3093 brdp->memsize = ECP_MEMSIZE;
3094 brdp->pagesize = ECP_ATPAGESIZE;
3095 brdp->init = stli_ecpinit;
3096 brdp->enable = stli_ecpenable;
3097 brdp->reenable = stli_ecpenable;
3098 brdp->disable = stli_ecpdisable;
3099 brdp->getmemptr = stli_ecpgetmemptr;
3100 brdp->intr = stli_ecpintr;
3101 brdp->reset = stli_ecpreset;
3102 name = "serial(EC8/64)";
3103 break;
3104
3105 case BRD_ECPE:
3106 brdp->memsize = ECP_MEMSIZE;
3107 brdp->pagesize = ECP_EIPAGESIZE;
3108 brdp->init = stli_ecpeiinit;
3109 brdp->enable = stli_ecpeienable;
3110 brdp->reenable = stli_ecpeienable;
3111 brdp->disable = stli_ecpeidisable;
3112 brdp->getmemptr = stli_ecpeigetmemptr;
3113 brdp->intr = stli_ecpintr;
3114 brdp->reset = stli_ecpeireset;
3115 name = "serial(EC8/64-EI)";
3116 break;
3117
3118 case BRD_ECPMC:
3119 brdp->memsize = ECP_MEMSIZE;
3120 brdp->pagesize = ECP_MCPAGESIZE;
3121 brdp->init = NULL;
3122 brdp->enable = stli_ecpmcenable;
3123 brdp->reenable = stli_ecpmcenable;
3124 brdp->disable = stli_ecpmcdisable;
3125 brdp->getmemptr = stli_ecpmcgetmemptr;
3126 brdp->intr = stli_ecpintr;
3127 brdp->reset = stli_ecpmcreset;
3128 name = "serial(EC8/64-MCA)";
3129 break;
3130
3131 case BRD_ECPPCI:
3132 brdp->memsize = ECP_PCIMEMSIZE;
3133 brdp->pagesize = ECP_PCIPAGESIZE;
3134 brdp->init = stli_ecppciinit;
3135 brdp->enable = NULL;
3136 brdp->reenable = NULL;
3137 brdp->disable = NULL;
3138 brdp->getmemptr = stli_ecppcigetmemptr;
3139 brdp->intr = stli_ecpintr;
3140 brdp->reset = stli_ecppcireset;
3141 name = "serial(EC/RA-PCI)";
3142 break;
3143
3144 default:
3145 retval = -EINVAL;
3146 goto err_reg;
3147 }
3148
3149
3150
3151
3152
3153
3154
3155 EBRDINIT(brdp);
3156
3157 brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize);
3158 if (brdp->membase == NULL) {
3159 retval = -ENOMEM;
3160 goto err_reg;
3161 }
3162
3163
3164
3165
3166
3167
3168 EBRDENABLE(brdp);
3169 sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3170 memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t));
3171 EBRDDISABLE(brdp);
3172
3173 if (sig.magic != cpu_to_le32(ECP_MAGIC)) {
3174 retval = -ENODEV;
3175 goto err_unmap;
3176 }
3177
3178
3179
3180
3181
3182 for (panelnr = 0, nxtid = 0; (panelnr < STL_MAXPANELS); panelnr++) {
3183 status = sig.panelid[nxtid];
3184 if ((status & ECH_PNLIDMASK) != nxtid)
3185 break;
3186
3187 brdp->panelids[panelnr] = status;
3188 nrports = (status & ECH_PNL16PORT) ? 16 : 8;
3189 if ((nrports == 16) && ((status & ECH_PNLXPID) == 0))
3190 nxtid++;
3191 brdp->panels[panelnr] = nrports;
3192 brdp->nrports += nrports;
3193 nxtid++;
3194 brdp->nrpanels++;
3195 }
3196
3197
3198 brdp->state |= BST_FOUND;
3199 return 0;
3200err_unmap:
3201 iounmap(brdp->membase);
3202 brdp->membase = NULL;
3203err_reg:
3204 release_region(brdp->iobase, brdp->iosize);
3205err:
3206 return retval;
3207}
3208
3209
3210
3211
3212
3213
3214
3215
3216static int stli_initonb(struct stlibrd *brdp)
3217{
3218 cdkonbsig_t sig;
3219 cdkonbsig_t __iomem *sigsp;
3220 char *name;
3221 int i, retval;
3222
3223
3224
3225
3226 if (brdp->iobase == 0 || brdp->memaddr == 0) {
3227 retval = -ENODEV;
3228 goto err;
3229 }
3230
3231 brdp->iosize = ONB_IOSIZE;
3232
3233 if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
3234 retval = -EIO;
3235 goto err;
3236 }
3237
3238
3239
3240
3241
3242
3243 switch (brdp->brdtype) {
3244 case BRD_ONBOARD:
3245 case BRD_ONBOARD2:
3246 brdp->memsize = ONB_MEMSIZE;
3247 brdp->pagesize = ONB_ATPAGESIZE;
3248 brdp->init = stli_onbinit;
3249 brdp->enable = stli_onbenable;
3250 brdp->reenable = stli_onbenable;
3251 brdp->disable = stli_onbdisable;
3252 brdp->getmemptr = stli_onbgetmemptr;
3253 brdp->intr = stli_ecpintr;
3254 brdp->reset = stli_onbreset;
3255 if (brdp->memaddr > 0x100000)
3256 brdp->enabval = ONB_MEMENABHI;
3257 else
3258 brdp->enabval = ONB_MEMENABLO;
3259 name = "serial(ONBoard)";
3260 break;
3261
3262 case BRD_ONBOARDE:
3263 brdp->memsize = ONB_EIMEMSIZE;
3264 brdp->pagesize = ONB_EIPAGESIZE;
3265 brdp->init = stli_onbeinit;
3266 brdp->enable = stli_onbeenable;
3267 brdp->reenable = stli_onbeenable;
3268 brdp->disable = stli_onbedisable;
3269 brdp->getmemptr = stli_onbegetmemptr;
3270 brdp->intr = stli_ecpintr;
3271 brdp->reset = stli_onbereset;
3272 name = "serial(ONBoard/E)";
3273 break;
3274
3275 case BRD_BRUMBY4:
3276 brdp->memsize = BBY_MEMSIZE;
3277 brdp->pagesize = BBY_PAGESIZE;
3278 brdp->init = stli_bbyinit;
3279 brdp->enable = NULL;
3280 brdp->reenable = NULL;
3281 brdp->disable = NULL;
3282 brdp->getmemptr = stli_bbygetmemptr;
3283 brdp->intr = stli_ecpintr;
3284 brdp->reset = stli_bbyreset;
3285 name = "serial(Brumby)";
3286 break;
3287
3288 case BRD_STALLION:
3289 brdp->memsize = STAL_MEMSIZE;
3290 brdp->pagesize = STAL_PAGESIZE;
3291 brdp->init = stli_stalinit;
3292 brdp->enable = NULL;
3293 brdp->reenable = NULL;
3294 brdp->disable = NULL;
3295 brdp->getmemptr = stli_stalgetmemptr;
3296 brdp->intr = stli_ecpintr;
3297 brdp->reset = stli_stalreset;
3298 name = "serial(Stallion)";
3299 break;
3300
3301 default:
3302 retval = -EINVAL;
3303 goto err_reg;
3304 }
3305
3306
3307
3308
3309
3310
3311
3312 EBRDINIT(brdp);
3313
3314 brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize);
3315 if (brdp->membase == NULL) {
3316 retval = -ENOMEM;
3317 goto err_reg;
3318 }
3319
3320
3321
3322
3323
3324
3325 EBRDENABLE(brdp);
3326 sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
3327 memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t));
3328 EBRDDISABLE(brdp);
3329
3330 if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) ||
3331 sig.magic1 != cpu_to_le16(ONB_MAGIC1) ||
3332 sig.magic2 != cpu_to_le16(ONB_MAGIC2) ||
3333 sig.magic3 != cpu_to_le16(ONB_MAGIC3)) {
3334 retval = -ENODEV;
3335 goto err_unmap;
3336 }
3337
3338
3339
3340
3341
3342 brdp->nrpanels = 1;
3343 if (sig.amask1) {
3344 brdp->nrports = 32;
3345 } else {
3346 for (i = 0; (i < 16); i++) {
3347 if (((sig.amask0 << i) & 0x8000) == 0)
3348 break;
3349 }
3350 brdp->nrports = i;
3351 }
3352 brdp->panels[0] = brdp->nrports;
3353
3354
3355 brdp->state |= BST_FOUND;
3356 return 0;
3357err_unmap:
3358 iounmap(brdp->membase);
3359 brdp->membase = NULL;
3360err_reg:
3361 release_region(brdp->iobase, brdp->iosize);
3362err:
3363 return retval;
3364}
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374static int stli_startbrd(struct stlibrd *brdp)
3375{
3376 cdkhdr_t __iomem *hdrp;
3377 cdkmem_t __iomem *memp;
3378 cdkasy_t __iomem *ap;
3379 unsigned long flags;
3380 unsigned int portnr, nrdevs, i;
3381 struct stliport *portp;
3382 int rc = 0;
3383 u32 memoff;
3384
3385 spin_lock_irqsave(&brd_lock, flags);
3386 EBRDENABLE(brdp);
3387 hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
3388 nrdevs = hdrp->nrdevs;
3389
3390#if 0
3391 printk("%s(%d): CDK version %d.%d.%d --> "
3392 "nrdevs=%d memp=%x hostp=%x slavep=%x\n",
3393 __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification),
3394 readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp),
3395 readl(&hdrp->slavep));
3396#endif
3397
3398 if (nrdevs < (brdp->nrports + 1)) {
3399 printk(KERN_ERR "istallion: slave failed to allocate memory for "
3400 "all devices, devices=%d\n", nrdevs);
3401 brdp->nrports = nrdevs - 1;
3402 }
3403 brdp->nrdevs = nrdevs;
3404 brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;
3405 brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;
3406 brdp->bitsize = (nrdevs + 7) / 8;
3407 memoff = readl(&hdrp->memp);
3408 if (memoff > brdp->memsize) {
3409 printk(KERN_ERR "istallion: corrupted shared memory region?\n");
3410 rc = -EIO;
3411 goto stli_donestartup;
3412 }
3413 memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);
3414 if (readw(&memp->dtype) != TYP_ASYNCTRL) {
3415 printk(KERN_ERR "istallion: no slave control device found\n");
3416 goto stli_donestartup;
3417 }
3418 memp++;
3419
3420
3421
3422
3423
3424
3425 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {
3426 if (readw(&memp->dtype) != TYP_ASYNC)
3427 break;
3428 portp = brdp->ports[portnr];
3429 if (portp == NULL)
3430 break;
3431 portp->devnr = i;
3432 portp->addr = readl(&memp->offset);
3433 portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs));
3434 portp->portidx = (unsigned char) (i / 8);
3435 portp->portbit = (unsigned char) (0x1 << (i % 8));
3436 }
3437
3438 writeb(0xff, &hdrp->slavereq);
3439
3440
3441
3442
3443
3444
3445 for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {
3446 portp = brdp->ports[portnr];
3447 if (portp == NULL)
3448 break;
3449 if (portp->addr == 0)
3450 break;
3451 ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
3452 if (ap != NULL) {
3453 portp->rxsize = readw(&ap->rxq.size);
3454 portp->txsize = readw(&ap->txq.size);
3455 portp->rxoffset = readl(&ap->rxq.offset);
3456 portp->txoffset = readl(&ap->txq.offset);
3457 }
3458 }
3459
3460stli_donestartup:
3461 EBRDDISABLE(brdp);
3462 spin_unlock_irqrestore(&brd_lock, flags);
3463
3464 if (rc == 0)
3465 brdp->state |= BST_STARTED;
3466
3467 if (! stli_timeron) {
3468 stli_timeron++;
3469 mod_timer(&stli_timerlist, STLI_TIMEOUT);
3470 }
3471
3472 return rc;
3473}
3474
3475
3476
3477
3478
3479
3480
3481static int __devinit stli_brdinit(struct stlibrd *brdp)
3482{
3483 int retval;
3484
3485 switch (brdp->brdtype) {
3486 case BRD_ECP:
3487 case BRD_ECPE:
3488 case BRD_ECPMC:
3489 case BRD_ECPPCI:
3490 retval = stli_initecp(brdp);
3491 break;
3492 case BRD_ONBOARD:
3493 case BRD_ONBOARDE:
3494 case BRD_ONBOARD2:
3495 case BRD_BRUMBY4:
3496 case BRD_STALLION:
3497 retval = stli_initonb(brdp);
3498 break;
3499 default:
3500 printk(KERN_ERR "istallion: board=%d is unknown board "
3501 "type=%d\n", brdp->brdnr, brdp->brdtype);
3502 retval = -ENODEV;
3503 }
3504
3505 if (retval)
3506 return retval;
3507
3508 stli_initports(brdp);
3509 printk(KERN_INFO "istallion: %s found, board=%d io=%x mem=%x "
3510 "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
3511 brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
3512 brdp->nrpanels, brdp->nrports);
3513 return 0;
3514}
3515
3516#if STLI_EISAPROBE != 0
3517
3518
3519
3520
3521
3522
3523
3524static int stli_eisamemprobe(struct stlibrd *brdp)
3525{
3526 cdkecpsig_t ecpsig, __iomem *ecpsigp;
3527 cdkonbsig_t onbsig, __iomem *onbsigp;
3528 int i, foundit;
3529
3530
3531
3532
3533
3534
3535
3536 if (brdp->brdtype == BRD_ECPE) {
3537 outb(0x1, (brdp->iobase + ECP_EIBRDENAB));
3538 outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
3539 udelay(10);
3540 outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
3541 udelay(500);
3542 stli_ecpeienable(brdp);
3543 } else if (brdp->brdtype == BRD_ONBOARDE) {
3544 outb(0x1, (brdp->iobase + ONB_EIBRDENAB));
3545 outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
3546 udelay(10);
3547 outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
3548 mdelay(100);
3549 outb(0x1, brdp->iobase);
3550 mdelay(1);
3551 stli_onbeenable(brdp);
3552 } else {
3553 return -ENODEV;
3554 }
3555
3556 foundit = 0;
3557 brdp->memsize = ECP_MEMSIZE;
3558
3559
3560
3561
3562
3563 for (i = 0; (i < stli_eisamempsize); i++) {
3564 brdp->memaddr = stli_eisamemprobeaddrs[i];
3565 brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize);
3566 if (brdp->membase == NULL)
3567 continue;
3568
3569 if (brdp->brdtype == BRD_ECPE) {
3570 ecpsigp = stli_ecpeigetmemptr(brdp,
3571 CDK_SIGADDR, __LINE__);
3572 memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
3573 if (ecpsig.magic == cpu_to_le32(ECP_MAGIC))
3574 foundit = 1;
3575 } else {
3576 onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp,
3577 CDK_SIGADDR, __LINE__);
3578 memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t));
3579 if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) &&
3580 (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) &&
3581 (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) &&
3582 (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3)))
3583 foundit = 1;
3584 }
3585
3586 iounmap(brdp->membase);
3587 if (foundit)
3588 break;
3589 }
3590
3591
3592
3593
3594
3595 if (brdp->brdtype == BRD_ECPE)
3596 stli_ecpeidisable(brdp);
3597 else
3598 stli_onbedisable(brdp);
3599
3600 if (! foundit) {
3601 brdp->memaddr = 0;
3602 brdp->membase = NULL;
3603 printk(KERN_ERR "istallion: failed to probe shared memory "
3604 "region for %s in EISA slot=%d\n",
3605 stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
3606 return -ENODEV;
3607 }
3608 return 0;
3609}
3610#endif
3611
3612static int stli_getbrdnr(void)
3613{
3614 unsigned int i;
3615
3616 for (i = 0; i < STL_MAXBRDS; i++) {
3617 if (!stli_brds[i]) {
3618 if (i >= stli_nrbrds)
3619 stli_nrbrds = i + 1;
3620 return i;
3621 }
3622 }
3623 return -1;
3624}
3625
3626#if STLI_EISAPROBE != 0
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639static int __init stli_findeisabrds(void)
3640{
3641 struct stlibrd *brdp;
3642 unsigned int iobase, eid, i;
3643 int brdnr, found = 0;
3644
3645
3646
3647
3648
3649 if (EISA_bus)
3650 return 0;
3651
3652
3653
3654
3655 for (iobase = 0x1000; (iobase <= 0xc000); iobase += 0x1000) {
3656 outb(0xff, (iobase + 0xc80));
3657 eid = inb(iobase + 0xc80);
3658 eid |= inb(iobase + 0xc81) << 8;
3659 if (eid != STL_EISAID)
3660 continue;
3661
3662
3663
3664
3665
3666 for (i = 0; (i < STL_MAXBRDS); i++) {
3667 brdp = stli_brds[i];
3668 if (brdp == NULL)
3669 continue;
3670 if (brdp->iobase == iobase)
3671 break;
3672 }
3673 if (i < STL_MAXBRDS)
3674 continue;
3675
3676
3677
3678
3679
3680 if ((brdp = stli_allocbrd()) == NULL)
3681 return found ? : -ENOMEM;
3682 brdnr = stli_getbrdnr();
3683 if (brdnr < 0)
3684 return found ? : -ENOMEM;
3685 brdp->brdnr = (unsigned int)brdnr;
3686 eid = inb(iobase + 0xc82);
3687 if (eid == ECP_EISAID)
3688 brdp->brdtype = BRD_ECPE;
3689 else if (eid == ONB_EISAID)
3690 brdp->brdtype = BRD_ONBOARDE;
3691 else
3692 brdp->brdtype = BRD_UNKNOWN;
3693 brdp->iobase = iobase;
3694 outb(0x1, (iobase + 0xc84));
3695 if (stli_eisamemprobe(brdp))
3696 outb(0, (iobase + 0xc84));
3697 if (stli_brdinit(brdp) < 0) {
3698 kfree(brdp);
3699 continue;
3700 }
3701
3702 stli_brds[brdp->brdnr] = brdp;
3703 found++;
3704
3705 for (i = 0; i < brdp->nrports; i++)
3706 tty_register_device(stli_serial,
3707 brdp->brdnr * STL_MAXPORTS + i, NULL);
3708 }
3709
3710 return found;
3711}
3712#else
3713static inline int stli_findeisabrds(void) { return 0; }
3714#endif
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730static int __devinit stli_pciprobe(struct pci_dev *pdev,
3731 const struct pci_device_id *ent)
3732{
3733 struct stlibrd *brdp;
3734 unsigned int i;
3735 int brdnr, retval = -EIO;
3736
3737 retval = pci_enable_device(pdev);
3738 if (retval)
3739 goto err;
3740 brdp = stli_allocbrd();
3741 if (brdp == NULL) {
3742 retval = -ENOMEM;
3743 goto err;
3744 }
3745 mutex_lock(&stli_brdslock);
3746 brdnr = stli_getbrdnr();
3747 if (brdnr < 0) {
3748 printk(KERN_INFO "istallion: too many boards found, "
3749 "maximum supported %d\n", STL_MAXBRDS);
3750 mutex_unlock(&stli_brdslock);
3751 retval = -EIO;
3752 goto err_fr;
3753 }
3754 brdp->brdnr = (unsigned int)brdnr;
3755 stli_brds[brdp->brdnr] = brdp;
3756 mutex_unlock(&stli_brdslock);
3757 brdp->brdtype = BRD_ECPPCI;
3758
3759
3760
3761
3762 brdp->iobase = pci_resource_start(pdev, 3);
3763 brdp->memaddr = pci_resource_start(pdev, 2);
3764 retval = stli_brdinit(brdp);
3765 if (retval)
3766 goto err_null;
3767
3768 brdp->state |= BST_PROBED;
3769 pci_set_drvdata(pdev, brdp);
3770
3771 EBRDENABLE(brdp);
3772 brdp->enable = NULL;
3773 brdp->disable = NULL;
3774
3775 for (i = 0; i < brdp->nrports; i++)
3776 tty_register_device(stli_serial, brdp->brdnr * STL_MAXPORTS + i,
3777 &pdev->dev);
3778
3779 return 0;
3780err_null:
3781 stli_brds[brdp->brdnr] = NULL;
3782err_fr:
3783 kfree(brdp);
3784err:
3785 return retval;
3786}
3787
3788static void stli_pciremove(struct pci_dev *pdev)
3789{
3790 struct stlibrd *brdp = pci_get_drvdata(pdev);
3791
3792 stli_cleanup_ports(brdp);
3793
3794 iounmap(brdp->membase);
3795 if (brdp->iosize > 0)
3796 release_region(brdp->iobase, brdp->iosize);
3797
3798 stli_brds[brdp->brdnr] = NULL;
3799 kfree(brdp);
3800}
3801
3802static struct pci_driver stli_pcidriver = {
3803 .name = "istallion",
3804 .id_table = istallion_pci_tbl,
3805 .probe = stli_pciprobe,
3806 .remove = __devexit_p(stli_pciremove)
3807};
3808
3809
3810
3811
3812
3813
3814static struct stlibrd *stli_allocbrd(void)
3815{
3816 struct stlibrd *brdp;
3817
3818 brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL);
3819 if (!brdp) {
3820 printk(KERN_ERR "istallion: failed to allocate memory "
3821 "(size=%Zd)\n", sizeof(struct stlibrd));
3822 return NULL;
3823 }
3824 brdp->magic = STLI_BOARDMAGIC;
3825 return brdp;
3826}
3827
3828
3829
3830
3831
3832
3833
3834
3835static int __init stli_initbrds(void)
3836{
3837 struct stlibrd *brdp, *nxtbrdp;
3838 struct stlconf conf;
3839 unsigned int i, j, found = 0;
3840 int retval;
3841
3842 for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp);
3843 stli_nrbrds++) {
3844 memset(&conf, 0, sizeof(conf));
3845 if (stli_parsebrd(&conf, stli_brdsp[stli_nrbrds]) == 0)
3846 continue;
3847 if ((brdp = stli_allocbrd()) == NULL)
3848 continue;
3849 brdp->brdnr = stli_nrbrds;
3850 brdp->brdtype = conf.brdtype;
3851 brdp->iobase = conf.ioaddr1;
3852 brdp->memaddr = conf.memaddr;
3853 if (stli_brdinit(brdp) < 0) {
3854 kfree(brdp);
3855 continue;
3856 }
3857 stli_brds[brdp->brdnr] = brdp;
3858 found++;
3859
3860 for (i = 0; i < brdp->nrports; i++)
3861 tty_register_device(stli_serial,
3862 brdp->brdnr * STL_MAXPORTS + i, NULL);
3863 }
3864
3865 retval = stli_findeisabrds();
3866 if (retval > 0)
3867 found += retval;
3868
3869
3870
3871
3872
3873
3874 stli_shared = 0;
3875 if (stli_nrbrds > 1) {
3876 for (i = 0; (i < stli_nrbrds); i++) {
3877 brdp = stli_brds[i];
3878 if (brdp == NULL)
3879 continue;
3880 for (j = i + 1; (j < stli_nrbrds); j++) {
3881 nxtbrdp = stli_brds[j];
3882 if (nxtbrdp == NULL)
3883 continue;
3884 if ((brdp->membase >= nxtbrdp->membase) &&
3885 (brdp->membase <= (nxtbrdp->membase +
3886 nxtbrdp->memsize - 1))) {
3887 stli_shared++;
3888 break;
3889 }
3890 }
3891 }
3892 }
3893
3894 if (stli_shared == 0) {
3895 for (i = 0; (i < stli_nrbrds); i++) {
3896 brdp = stli_brds[i];
3897 if (brdp == NULL)
3898 continue;
3899 if (brdp->state & BST_FOUND) {
3900 EBRDENABLE(brdp);
3901 brdp->enable = NULL;
3902 brdp->disable = NULL;
3903 }
3904 }
3905 }
3906
3907 retval = pci_register_driver(&stli_pcidriver);
3908 if (retval && found == 0) {
3909 printk(KERN_ERR "Neither isa nor eisa cards found nor pci "
3910 "driver can be registered!\n");
3911 goto err;
3912 }
3913
3914 return 0;
3915err:
3916 return retval;
3917}
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp)
3928{
3929 unsigned long flags;
3930 void __iomem *memptr;
3931 struct stlibrd *brdp;
3932 unsigned int brdnr;
3933 int size, n;
3934 void *p;
3935 loff_t off = *offp;
3936
3937 brdnr = iminor(fp->f_path.dentry->d_inode);
3938 if (brdnr >= stli_nrbrds)
3939 return -ENODEV;
3940 brdp = stli_brds[brdnr];
3941 if (brdp == NULL)
3942 return -ENODEV;
3943 if (brdp->state == 0)
3944 return -ENODEV;
3945 if (off >= brdp->memsize || off + count < off)
3946 return 0;
3947
3948 size = min(count, (size_t)(brdp->memsize - off));
3949
3950
3951
3952
3953
3954 p = (void *)__get_free_page(GFP_KERNEL);
3955 if(p == NULL)
3956 return -ENOMEM;
3957
3958 while (size > 0) {
3959 spin_lock_irqsave(&brd_lock, flags);
3960 EBRDENABLE(brdp);
3961 memptr = EBRDGETMEMPTR(brdp, off);
3962 n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
3963 n = min(n, (int)PAGE_SIZE);
3964 memcpy_fromio(p, memptr, n);
3965 EBRDDISABLE(brdp);
3966 spin_unlock_irqrestore(&brd_lock, flags);
3967 if (copy_to_user(buf, p, n)) {
3968 count = -EFAULT;
3969 goto out;
3970 }
3971 off += n;
3972 buf += n;
3973 size -= n;
3974 }
3975out:
3976 *offp = off;
3977 free_page((unsigned long)p);
3978 return count;
3979}
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp)
3992{
3993 unsigned long flags;
3994 void __iomem *memptr;
3995 struct stlibrd *brdp;
3996 char __user *chbuf;
3997 unsigned int brdnr;
3998 int size, n;
3999 void *p;
4000 loff_t off = *offp;
4001
4002 brdnr = iminor(fp->f_path.dentry->d_inode);
4003
4004 if (brdnr >= stli_nrbrds)
4005 return -ENODEV;
4006 brdp = stli_brds[brdnr];
4007 if (brdp == NULL)
4008 return -ENODEV;
4009 if (brdp->state == 0)
4010 return -ENODEV;
4011 if (off >= brdp->memsize || off + count < off)
4012 return 0;
4013
4014 chbuf = (char __user *) buf;
4015 size = min(count, (size_t)(brdp->memsize - off));
4016
4017
4018
4019
4020
4021 p = (void *)__get_free_page(GFP_KERNEL);
4022 if(p == NULL)
4023 return -ENOMEM;
4024
4025 while (size > 0) {
4026 n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
4027 n = min(n, (int)PAGE_SIZE);
4028 if (copy_from_user(p, chbuf, n)) {
4029 if (count == 0)
4030 count = -EFAULT;
4031 goto out;
4032 }
4033 spin_lock_irqsave(&brd_lock, flags);
4034 EBRDENABLE(brdp);
4035 memptr = EBRDGETMEMPTR(brdp, off);
4036 memcpy_toio(memptr, p, n);
4037 EBRDDISABLE(brdp);
4038 spin_unlock_irqrestore(&brd_lock, flags);
4039 off += n;
4040 chbuf += n;
4041 size -= n;
4042 }
4043out:
4044 free_page((unsigned long) p);
4045 *offp = off;
4046 return count;
4047}
4048
4049
4050
4051
4052
4053
4054
4055static int stli_getbrdstats(combrd_t __user *bp)
4056{
4057 struct stlibrd *brdp;
4058 unsigned int i;
4059
4060 if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t)))
4061 return -EFAULT;
4062 if (stli_brdstats.brd >= STL_MAXBRDS)
4063 return -ENODEV;
4064 brdp = stli_brds[stli_brdstats.brd];
4065 if (brdp == NULL)
4066 return -ENODEV;
4067
4068 memset(&stli_brdstats, 0, sizeof(combrd_t));
4069 stli_brdstats.brd = brdp->brdnr;
4070 stli_brdstats.type = brdp->brdtype;
4071 stli_brdstats.hwid = 0;
4072 stli_brdstats.state = brdp->state;
4073 stli_brdstats.ioaddr = brdp->iobase;
4074 stli_brdstats.memaddr = brdp->memaddr;
4075 stli_brdstats.nrpanels = brdp->nrpanels;
4076 stli_brdstats.nrports = brdp->nrports;
4077 for (i = 0; (i < brdp->nrpanels); i++) {
4078 stli_brdstats.panels[i].panel = i;
4079 stli_brdstats.panels[i].hwid = brdp->panelids[i];
4080 stli_brdstats.panels[i].nrports = brdp->panels[i];
4081 }
4082
4083 if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t)))
4084 return -EFAULT;
4085 return 0;
4086}
4087
4088
4089
4090
4091
4092
4093
4094static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr,
4095 unsigned int portnr)
4096{
4097 struct stlibrd *brdp;
4098 unsigned int i;
4099
4100 if (brdnr >= STL_MAXBRDS)
4101 return NULL;
4102 brdp = stli_brds[brdnr];
4103 if (brdp == NULL)
4104 return NULL;
4105 for (i = 0; (i < panelnr); i++)
4106 portnr += brdp->panels[i];
4107 if (portnr >= brdp->nrports)
4108 return NULL;
4109 return brdp->ports[portnr];
4110}
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp)
4121{
4122 unsigned long flags;
4123 struct stlibrd *brdp;
4124 int rc;
4125
4126 memset(&stli_comstats, 0, sizeof(comstats_t));
4127
4128 if (portp == NULL)
4129 return -ENODEV;
4130 brdp = stli_brds[portp->brdnr];
4131 if (brdp == NULL)
4132 return -ENODEV;
4133
4134 if (brdp->state & BST_STARTED) {
4135 if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,
4136 &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
4137 return rc;
4138 } else {
4139 memset(&stli_cdkstats, 0, sizeof(asystats_t));
4140 }
4141
4142 stli_comstats.brd = portp->brdnr;
4143 stli_comstats.panel = portp->panelnr;
4144 stli_comstats.port = portp->portnr;
4145 stli_comstats.state = portp->state;
4146 stli_comstats.flags = portp->port.flags;
4147
4148 spin_lock_irqsave(&brd_lock, flags);
4149 if (tty != NULL) {
4150 if (portp->port.tty == tty) {
4151 stli_comstats.ttystate = tty->flags;
4152 stli_comstats.rxbuffered = -1;
4153 if (tty->termios != NULL) {
4154 stli_comstats.cflags = tty->termios->c_cflag;
4155 stli_comstats.iflags = tty->termios->c_iflag;
4156 stli_comstats.oflags = tty->termios->c_oflag;
4157 stli_comstats.lflags = tty->termios->c_lflag;
4158 }
4159 }
4160 }
4161 spin_unlock_irqrestore(&brd_lock, flags);
4162
4163 stli_comstats.txtotal = stli_cdkstats.txchars;
4164 stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;
4165 stli_comstats.txbuffered = stli_cdkstats.txringq;
4166 stli_comstats.rxbuffered += stli_cdkstats.rxringq;
4167 stli_comstats.rxoverrun = stli_cdkstats.overruns;
4168 stli_comstats.rxparity = stli_cdkstats.parity;
4169 stli_comstats.rxframing = stli_cdkstats.framing;
4170 stli_comstats.rxlost = stli_cdkstats.ringover;
4171 stli_comstats.rxbreaks = stli_cdkstats.rxbreaks;
4172 stli_comstats.txbreaks = stli_cdkstats.txbreaks;
4173 stli_comstats.txxon = stli_cdkstats.txstart;
4174 stli_comstats.txxoff = stli_cdkstats.txstop;
4175 stli_comstats.rxxon = stli_cdkstats.rxstart;
4176 stli_comstats.rxxoff = stli_cdkstats.rxstop;
4177 stli_comstats.rxrtsoff = stli_cdkstats.rtscnt / 2;
4178 stli_comstats.rxrtson = stli_cdkstats.rtscnt - stli_comstats.rxrtsoff;
4179 stli_comstats.modem = stli_cdkstats.dcdcnt;
4180 stli_comstats.hwid = stli_cdkstats.hwid;
4181 stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
4182
4183 return 0;
4184}
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194static int stli_getportstats(struct tty_struct *tty, struct stliport *portp,
4195 comstats_t __user *cp)
4196{
4197 struct stlibrd *brdp;
4198 int rc;
4199
4200 if (!portp) {
4201 if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))
4202 return -EFAULT;
4203 portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
4204 stli_comstats.port);
4205 if (!portp)
4206 return -ENODEV;
4207 }
4208
4209 brdp = stli_brds[portp->brdnr];
4210 if (!brdp)
4211 return -ENODEV;
4212
4213 if ((rc = stli_portcmdstats(tty, portp)) < 0)
4214 return rc;
4215
4216 return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ?
4217 -EFAULT : 0;
4218}
4219
4220
4221
4222
4223
4224
4225
4226static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp)
4227{
4228 struct stlibrd *brdp;
4229 int rc;
4230
4231 if (!portp) {
4232 if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))
4233 return -EFAULT;
4234 portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
4235 stli_comstats.port);
4236 if (!portp)
4237 return -ENODEV;
4238 }
4239
4240 brdp = stli_brds[portp->brdnr];
4241 if (!brdp)
4242 return -ENODEV;
4243
4244 if (brdp->state & BST_STARTED) {
4245 if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0)
4246 return rc;
4247 }
4248
4249 memset(&stli_comstats, 0, sizeof(comstats_t));
4250 stli_comstats.brd = portp->brdnr;
4251 stli_comstats.panel = portp->panelnr;
4252 stli_comstats.port = portp->portnr;
4253
4254 if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t)))
4255 return -EFAULT;
4256 return 0;
4257}
4258
4259
4260
4261
4262
4263
4264
4265static int stli_getportstruct(struct stliport __user *arg)
4266{
4267 struct stliport stli_dummyport;
4268 struct stliport *portp;
4269
4270 if (copy_from_user(&stli_dummyport, arg, sizeof(struct stliport)))
4271 return -EFAULT;
4272 portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr,
4273 stli_dummyport.portnr);
4274 if (!portp)
4275 return -ENODEV;
4276 if (copy_to_user(arg, portp, sizeof(struct stliport)))
4277 return -EFAULT;
4278 return 0;
4279}
4280
4281
4282
4283
4284
4285
4286
4287static int stli_getbrdstruct(struct stlibrd __user *arg)
4288{
4289 struct stlibrd stli_dummybrd;
4290 struct stlibrd *brdp;
4291
4292 if (copy_from_user(&stli_dummybrd, arg, sizeof(struct stlibrd)))
4293 return -EFAULT;
4294 if (stli_dummybrd.brdnr >= STL_MAXBRDS)
4295 return -ENODEV;
4296 brdp = stli_brds[stli_dummybrd.brdnr];
4297 if (!brdp)
4298 return -ENODEV;
4299 if (copy_to_user(arg, brdp, sizeof(struct stlibrd)))
4300 return -EFAULT;
4301 return 0;
4302}
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
4313{
4314 struct stlibrd *brdp;
4315 int brdnr, rc, done;
4316 void __user *argp = (void __user *)arg;
4317
4318
4319
4320
4321 done = 0;
4322 rc = 0;
4323
4324 lock_kernel();
4325
4326 switch (cmd) {
4327 case COM_GETPORTSTATS:
4328 rc = stli_getportstats(NULL, NULL, argp);
4329 done++;
4330 break;
4331 case COM_CLRPORTSTATS:
4332 rc = stli_clrportstats(NULL, argp);
4333 done++;
4334 break;
4335 case COM_GETBRDSTATS:
4336 rc = stli_getbrdstats(argp);
4337 done++;
4338 break;
4339 case COM_READPORT:
4340 rc = stli_getportstruct(argp);
4341 done++;
4342 break;
4343 case COM_READBOARD:
4344 rc = stli_getbrdstruct(argp);
4345 done++;
4346 break;
4347 }
4348 unlock_kernel();
4349
4350 if (done)
4351 return rc;
4352
4353
4354
4355
4356
4357 brdnr = iminor(ip);
4358 if (brdnr >= STL_MAXBRDS)
4359 return -ENODEV;
4360 brdp = stli_brds[brdnr];
4361 if (!brdp)
4362 return -ENODEV;
4363 if (brdp->state == 0)
4364 return -ENODEV;
4365
4366 lock_kernel();
4367
4368 switch (cmd) {
4369 case STL_BINTR:
4370 EBRDINTR(brdp);
4371 break;
4372 case STL_BSTART:
4373 rc = stli_startbrd(brdp);
4374 break;
4375 case STL_BSTOP:
4376 brdp->state &= ~BST_STARTED;
4377 break;
4378 case STL_BRESET:
4379 brdp->state &= ~BST_STARTED;
4380 EBRDRESET(brdp);
4381 if (stli_shared == 0) {
4382 if (brdp->reenable != NULL)
4383 (* brdp->reenable)(brdp);
4384 }
4385 break;
4386 default:
4387 rc = -ENOIOCTLCMD;
4388 break;
4389 }
4390 unlock_kernel();
4391 return rc;
4392}
4393
4394static const struct tty_operations stli_ops = {
4395 .open = stli_open,
4396 .close = stli_close,
4397 .write = stli_write,
4398 .put_char = stli_putchar,
4399 .flush_chars = stli_flushchars,
4400 .write_room = stli_writeroom,
4401 .chars_in_buffer = stli_charsinbuffer,
4402 .ioctl = stli_ioctl,
4403 .set_termios = stli_settermios,
4404 .throttle = stli_throttle,
4405 .unthrottle = stli_unthrottle,
4406 .stop = stli_stop,
4407 .start = stli_start,
4408 .hangup = stli_hangup,
4409 .flush_buffer = stli_flushbuffer,
4410 .break_ctl = stli_breakctl,
4411 .wait_until_sent = stli_waituntilsent,
4412 .send_xchar = stli_sendxchar,
4413 .tiocmget = stli_tiocmget,
4414 .tiocmset = stli_tiocmset,
4415 .proc_fops = &stli_proc_fops,
4416};
4417
4418static const struct tty_port_operations stli_port_ops = {
4419 .carrier_raised = stli_carrier_raised,
4420 .raise_dtr_rts = stli_raise_dtr_rts,
4421};
4422
4423
4424
4425
4426
4427
4428static void istallion_cleanup_isa(void)
4429{
4430 struct stlibrd *brdp;
4431 unsigned int j;
4432
4433 for (j = 0; (j < stli_nrbrds); j++) {
4434 if ((brdp = stli_brds[j]) == NULL || (brdp->state & BST_PROBED))
4435 continue;
4436
4437 stli_cleanup_ports(brdp);
4438
4439 iounmap(brdp->membase);
4440 if (brdp->iosize > 0)
4441 release_region(brdp->iobase, brdp->iosize);
4442 kfree(brdp);
4443 stli_brds[j] = NULL;
4444 }
4445}
4446
4447static int __init istallion_module_init(void)
4448{
4449 unsigned int i;
4450 int retval;
4451
4452 printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
4453
4454 spin_lock_init(&stli_lock);
4455 spin_lock_init(&brd_lock);
4456
4457 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
4458 if (!stli_txcookbuf) {
4459 printk(KERN_ERR "istallion: failed to allocate memory "
4460 "(size=%d)\n", STLI_TXBUFSIZE);
4461 retval = -ENOMEM;
4462 goto err;
4463 }
4464
4465 stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
4466 if (!stli_serial) {
4467 retval = -ENOMEM;
4468 goto err_free;
4469 }
4470
4471 stli_serial->owner = THIS_MODULE;
4472 stli_serial->driver_name = stli_drvname;
4473 stli_serial->name = stli_serialname;
4474 stli_serial->major = STL_SERIALMAJOR;
4475 stli_serial->minor_start = 0;
4476 stli_serial->type = TTY_DRIVER_TYPE_SERIAL;
4477 stli_serial->subtype = SERIAL_TYPE_NORMAL;
4478 stli_serial->init_termios = stli_deftermios;
4479 stli_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
4480 tty_set_operations(stli_serial, &stli_ops);
4481
4482 retval = tty_register_driver(stli_serial);
4483 if (retval) {
4484 printk(KERN_ERR "istallion: failed to register serial driver\n");
4485 goto err_ttyput;
4486 }
4487
4488 retval = stli_initbrds();
4489 if (retval)
4490 goto err_ttyunr;
4491
4492
4493
4494
4495
4496 retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem);
4497 if (retval) {
4498 printk(KERN_ERR "istallion: failed to register serial memory "
4499 "device\n");
4500 goto err_deinit;
4501 }
4502
4503 istallion_class = class_create(THIS_MODULE, "staliomem");
4504 for (i = 0; i < 4; i++)
4505 device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
4506 NULL, "staliomem%d", i);
4507
4508 return 0;
4509err_deinit:
4510 pci_unregister_driver(&stli_pcidriver);
4511 istallion_cleanup_isa();
4512err_ttyunr:
4513 tty_unregister_driver(stli_serial);
4514err_ttyput:
4515 put_tty_driver(stli_serial);
4516err_free:
4517 kfree(stli_txcookbuf);
4518err:
4519 return retval;
4520}
4521
4522
4523
4524static void __exit istallion_module_exit(void)
4525{
4526 unsigned int j;
4527
4528 printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
4529 stli_drvversion);
4530
4531 if (stli_timeron) {
4532 stli_timeron = 0;
4533 del_timer_sync(&stli_timerlist);
4534 }
4535
4536 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
4537
4538 for (j = 0; j < 4; j++)
4539 device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j));
4540 class_destroy(istallion_class);
4541
4542 pci_unregister_driver(&stli_pcidriver);
4543 istallion_cleanup_isa();
4544
4545 tty_unregister_driver(stli_serial);
4546 put_tty_driver(stli_serial);
4547
4548 kfree(stli_txcookbuf);
4549}
4550
4551module_init(istallion_module_init);
4552module_exit(istallion_module_exit);
4553