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