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