1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/version.h>
32#include <linux/slab.h>
33#include <linux/interrupt.h>
34#include <linux/tty.h>
35#include <linux/tty_flip.h>
36#include <linux/serial.h>
37#include <linux/cd1400.h>
38#include <linux/sc26198.h>
39#include <linux/comstats.h>
40#include <linux/stallion.h>
41#include <linux/ioport.h>
42#include <linux/init.h>
43#include <linux/smp_lock.h>
44#include <linux/devfs_fs_kernel.h>
45
46#include <asm/io.h>
47#include <asm/uaccess.h>
48
49#ifdef CONFIG_PCI
50#include <linux/pci.h>
51#endif
52
53
54
55
56
57
58
59
60#define BRD_EASYIO 20
61#define BRD_ECH 21
62#define BRD_ECHMC 22
63#define BRD_ECHPCI 26
64#define BRD_ECH64PCI 27
65#define BRD_EASYIOPCI 28
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92typedef struct {
93 int brdtype;
94 int ioaddr1;
95 int ioaddr2;
96 unsigned long memaddr;
97 int irq;
98 int irqtype;
99} stlconf_t;
100
101static stlconf_t stl_brdconf[] = {
102
103};
104
105static int stl_nrbrds = sizeof(stl_brdconf) / sizeof(stlconf_t);
106
107
108
109
110
111
112
113#ifndef STL_SIOMEMMAJOR
114#define STL_SIOMEMMAJOR 28
115#endif
116#ifndef STL_SERIALMAJOR
117#define STL_SERIALMAJOR 24
118#endif
119#ifndef STL_CALLOUTMAJOR
120#define STL_CALLOUTMAJOR 25
121#endif
122
123#define STL_DRVTYPSERIAL 1
124#define STL_DRVTYPCALLOUT 2
125
126
127
128
129
130#define STL_TXBUFLOW 512
131#define STL_TXBUFSIZE 4096
132
133
134
135
136
137
138
139static char *stl_drvtitle = "Stallion Multiport Serial Driver";
140static char *stl_drvname = "stallion";
141static char *stl_drvversion = "5.6.0";
142#ifdef CONFIG_DEVFS_FS
143static char *stl_serialname = "tts/E%d";
144static char *stl_calloutname = "cua/E%d";
145#else
146static char *stl_serialname = "ttyE";
147static char *stl_calloutname = "cue";
148#endif
149
150static struct tty_driver stl_serial;
151static struct tty_driver stl_callout;
152static struct tty_struct *stl_ttys[STL_MAXDEVS];
153static struct termios *stl_termios[STL_MAXDEVS];
154static struct termios *stl_termioslocked[STL_MAXDEVS];
155static int stl_refcount;
156
157
158
159
160
161
162
163
164static char *stl_tmpwritebuf;
165static DECLARE_MUTEX(stl_tmpwritesem);
166
167
168
169
170
171
172static struct termios stl_deftermios = {
173 c_cflag: (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
174 c_cc: INIT_C_CC,
175};
176
177
178
179
180
181static comstats_t stl_comstats;
182static combrd_t stl_brdstats;
183static stlbrd_t stl_dummybrd;
184static stlport_t stl_dummyport;
185
186
187
188
189static char stl_unwanted[SC26198_RXFIFOSIZE];
190
191
192
193static stlbrd_t *stl_brds[STL_MAXBRDS];
194
195
196
197
198
199#define BRD_FOUND 0x1
200
201
202
203
204
205
206#define ASYI_TXBUSY 1
207#define ASYI_TXLOW 2
208#define ASYI_DCDCHANGE 3
209#define ASYI_TXFLOWED 4
210
211
212
213
214
215static char *stl_brdnames[] = {
216 (char *) NULL,
217 (char *) NULL,
218 (char *) NULL,
219 (char *) NULL,
220 (char *) NULL,
221 (char *) NULL,
222 (char *) NULL,
223 (char *) NULL,
224 (char *) NULL,
225 (char *) NULL,
226 (char *) NULL,
227 (char *) NULL,
228 (char *) NULL,
229 (char *) NULL,
230 (char *) NULL,
231 (char *) NULL,
232 (char *) NULL,
233 (char *) NULL,
234 (char *) NULL,
235 (char *) NULL,
236 "EasyIO",
237 "EC8/32-AT",
238 "EC8/32-MC",
239 (char *) NULL,
240 (char *) NULL,
241 (char *) NULL,
242 "EC8/32-PCI",
243 "EC8/64-PCI",
244 "EasyIO-PCI",
245};
246
247
248
249#ifdef MODULE
250
251
252
253
254
255
256static char *board0[4];
257static char *board1[4];
258static char *board2[4];
259static char *board3[4];
260
261static char **stl_brdsp[] = {
262 (char **) &board0,
263 (char **) &board1,
264 (char **) &board2,
265 (char **) &board3
266};
267
268
269
270
271
272
273typedef struct stlbrdtype {
274 char *name;
275 int type;
276} stlbrdtype_t;
277
278static stlbrdtype_t stl_brdstr[] = {
279 { "easyio", BRD_EASYIO },
280 { "eio", BRD_EASYIO },
281 { "20", BRD_EASYIO },
282 { "ec8/32", BRD_ECH },
283 { "ec8/32-at", BRD_ECH },
284 { "ec8/32-isa", BRD_ECH },
285 { "ech", BRD_ECH },
286 { "echat", BRD_ECH },
287 { "21", BRD_ECH },
288 { "ec8/32-mc", BRD_ECHMC },
289 { "ec8/32-mca", BRD_ECHMC },
290 { "echmc", BRD_ECHMC },
291 { "echmca", BRD_ECHMC },
292 { "22", BRD_ECHMC },
293 { "ec8/32-pc", BRD_ECHPCI },
294 { "ec8/32-pci", BRD_ECHPCI },
295 { "26", BRD_ECHPCI },
296 { "ec8/64-pc", BRD_ECH64PCI },
297 { "ec8/64-pci", BRD_ECH64PCI },
298 { "ech-pci", BRD_ECH64PCI },
299 { "echpci", BRD_ECH64PCI },
300 { "echpc", BRD_ECH64PCI },
301 { "27", BRD_ECH64PCI },
302 { "easyio-pc", BRD_EASYIOPCI },
303 { "easyio-pci", BRD_EASYIOPCI },
304 { "eio-pci", BRD_EASYIOPCI },
305 { "eiopci", BRD_EASYIOPCI },
306 { "28", BRD_EASYIOPCI },
307};
308
309
310
311
312MODULE_AUTHOR("Greg Ungerer");
313MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
314MODULE_LICENSE("GPL");
315
316MODULE_PARM(board0, "1-4s");
317MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]");
318MODULE_PARM(board1, "1-4s");
319MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]");
320MODULE_PARM(board2, "1-4s");
321MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]");
322MODULE_PARM(board3, "1-4s");
323MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]");
324
325#endif
326
327
328
329
330
331
332
333
334#define EIO_8PORTRS 0x04
335#define EIO_4PORTRS 0x05
336#define EIO_8PORTDI 0x00
337#define EIO_8PORTM 0x06
338#define EIO_MK3 0x03
339#define EIO_IDBITMASK 0x07
340
341#define EIO_BRDMASK 0xf0
342#define ID_BRD4 0x10
343#define ID_BRD8 0x20
344#define ID_BRD16 0x30
345
346#define EIO_INTRPEND 0x08
347#define EIO_INTEDGE 0x00
348#define EIO_INTLEVEL 0x08
349#define EIO_0WS 0x10
350
351#define ECH_ID 0xa0
352#define ECH_IDBITMASK 0xe0
353#define ECH_BRDENABLE 0x08
354#define ECH_BRDDISABLE 0x00
355#define ECH_INTENABLE 0x01
356#define ECH_INTDISABLE 0x00
357#define ECH_INTLEVEL 0x02
358#define ECH_INTEDGE 0x00
359#define ECH_INTRPEND 0x01
360#define ECH_BRDRESET 0x01
361
362#define ECHMC_INTENABLE 0x01
363#define ECHMC_BRDRESET 0x02
364
365#define ECH_PNLSTATUS 2
366#define ECH_PNL16PORT 0x20
367#define ECH_PNLIDMASK 0x07
368#define ECH_PNLXPID 0x40
369#define ECH_PNLINTRPEND 0x80
370
371#define ECH_ADDR2MASK 0x1e0
372
373
374
375
376
377
378static unsigned char stl_vecmap[] = {
379 0xff, 0xff, 0xff, 0x04, 0x06, 0x05, 0xff, 0x07,
380 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03
381};
382
383
384
385
386
387
388
389
390#define BRDENABLE(brdnr,pagenr) \
391 if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \
392 outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDENABLE), \
393 stl_brds[(brdnr)]->ioctrl); \
394 else if (stl_brds[(brdnr)]->brdtype == BRD_ECHPCI) \
395 outb((pagenr), stl_brds[(brdnr)]->ioctrl);
396
397#define BRDDISABLE(brdnr) \
398 if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \
399 outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE), \
400 stl_brds[(brdnr)]->ioctrl);
401
402#define STL_CD1400MAXBAUD 230400
403#define STL_SC26198MAXBAUD 460800
404
405#define STL_BAUDBASE 115200
406#define STL_CLOSEDELAY (5 * HZ / 10)
407
408
409
410#ifdef CONFIG_PCI
411
412
413
414
415#ifndef PCI_VENDOR_ID_STALLION
416#define PCI_VENDOR_ID_STALLION 0x124d
417#endif
418#ifndef PCI_DEVICE_ID_ECHPCI832
419#define PCI_DEVICE_ID_ECHPCI832 0x0000
420#endif
421#ifndef PCI_DEVICE_ID_ECHPCI864
422#define PCI_DEVICE_ID_ECHPCI864 0x0002
423#endif
424#ifndef PCI_DEVICE_ID_EIOPCI
425#define PCI_DEVICE_ID_EIOPCI 0x0003
426#endif
427
428
429
430
431typedef struct stlpcibrd {
432 unsigned short vendid;
433 unsigned short devid;
434 int brdtype;
435} stlpcibrd_t;
436
437static stlpcibrd_t stl_pcibrds[] = {
438 { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864, BRD_ECH64PCI },
439 { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI, BRD_EASYIOPCI },
440 { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832, BRD_ECHPCI },
441 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI },
442};
443
444static int stl_nrpcibrds = sizeof(stl_pcibrds) / sizeof(stlpcibrd_t);
445
446#endif
447
448
449
450
451
452
453#define MINOR2BRD(min) (((min) & 0xc0) >> 6)
454#define MINOR2PORT(min) ((min) & 0x3f)
455
456
457
458
459
460
461static unsigned int stl_baudrates[] = {
462 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
463 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
464};
465
466
467
468
469#undef MIN
470#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
471
472#undef TOLOWER
473#define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
474
475
476
477
478
479
480
481#ifdef MODULE
482int init_module(void);
483void cleanup_module(void);
484static void stl_argbrds(void);
485static int stl_parsebrd(stlconf_t *confp, char **argp);
486
487static unsigned long stl_atol(char *str);
488#endif
489
490int stl_init(void);
491static int stl_open(struct tty_struct *tty, struct file *filp);
492static void stl_close(struct tty_struct *tty, struct file *filp);
493static int stl_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
494static void stl_putchar(struct tty_struct *tty, unsigned char ch);
495static void stl_flushchars(struct tty_struct *tty);
496static int stl_writeroom(struct tty_struct *tty);
497static int stl_charsinbuffer(struct tty_struct *tty);
498static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
499static void stl_settermios(struct tty_struct *tty, struct termios *old);
500static void stl_throttle(struct tty_struct *tty);
501static void stl_unthrottle(struct tty_struct *tty);
502static void stl_stop(struct tty_struct *tty);
503static void stl_start(struct tty_struct *tty);
504static void stl_flushbuffer(struct tty_struct *tty);
505static void stl_breakctl(struct tty_struct *tty, int state);
506static void stl_waituntilsent(struct tty_struct *tty, int timeout);
507static void stl_sendxchar(struct tty_struct *tty, char ch);
508static void stl_hangup(struct tty_struct *tty);
509static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
510static int stl_portinfo(stlport_t *portp, int portnr, char *pos);
511static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data);
512
513static int stl_brdinit(stlbrd_t *brdp);
514static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
515static void stl_getserial(stlport_t *portp, struct serial_struct *sp);
516static int stl_setserial(stlport_t *portp, struct serial_struct *sp);
517static int stl_getbrdstats(combrd_t *bp);
518static int stl_getportstats(stlport_t *portp, comstats_t *cp);
519static int stl_clrportstats(stlport_t *portp, comstats_t *cp);
520static int stl_getportstruct(unsigned long arg);
521static int stl_getbrdstruct(unsigned long arg);
522static int stl_waitcarrier(stlport_t *portp, struct file *filp);
523static void stl_delay(int len);
524static void stl_intr(int irq, void *dev_id, struct pt_regs *regs);
525static void stl_eiointr(stlbrd_t *brdp);
526static void stl_echatintr(stlbrd_t *brdp);
527static void stl_echmcaintr(stlbrd_t *brdp);
528static void stl_echpciintr(stlbrd_t *brdp);
529static void stl_echpci64intr(stlbrd_t *brdp);
530static void stl_offintr(void *private);
531static void *stl_memalloc(int len);
532static stlbrd_t *stl_allocbrd(void);
533static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
534
535static inline int stl_initbrds(void);
536static inline int stl_initeio(stlbrd_t *brdp);
537static inline int stl_initech(stlbrd_t *brdp);
538static inline int stl_getbrdnr(void);
539
540#ifdef CONFIG_PCI
541static inline int stl_findpcibrds(void);
542static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp);
543#endif
544
545
546
547
548static void stl_cd1400setreg(stlport_t *portp, int regnr, int value);
549static int stl_cd1400getreg(stlport_t *portp, int regnr);
550static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value);
551static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
552static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
553static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp);
554static int stl_cd1400getsignals(stlport_t *portp);
555static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts);
556static void stl_cd1400ccrwait(stlport_t *portp);
557static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx);
558static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx);
559static void stl_cd1400disableintrs(stlport_t *portp);
560static void stl_cd1400sendbreak(stlport_t *portp, int len);
561static void stl_cd1400flowctrl(stlport_t *portp, int state);
562static void stl_cd1400sendflow(stlport_t *portp, int state);
563static void stl_cd1400flush(stlport_t *portp);
564static int stl_cd1400datastate(stlport_t *portp);
565static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase);
566static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase);
567static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr);
568static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr);
569static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr);
570
571static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr);
572
573
574
575
576static void stl_sc26198setreg(stlport_t *portp, int regnr, int value);
577static int stl_sc26198getreg(stlport_t *portp, int regnr);
578static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value);
579static int stl_sc26198getglobreg(stlport_t *portp, int regnr);
580static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
581static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
582static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp);
583static int stl_sc26198getsignals(stlport_t *portp);
584static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts);
585static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx);
586static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx);
587static void stl_sc26198disableintrs(stlport_t *portp);
588static void stl_sc26198sendbreak(stlport_t *portp, int len);
589static void stl_sc26198flowctrl(stlport_t *portp, int state);
590static void stl_sc26198sendflow(stlport_t *portp, int state);
591static void stl_sc26198flush(stlport_t *portp);
592static int stl_sc26198datastate(stlport_t *portp);
593static void stl_sc26198wait(stlport_t *portp);
594static void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty);
595static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase);
596static void stl_sc26198txisr(stlport_t *port);
597static void stl_sc26198rxisr(stlport_t *port, unsigned int iack);
598static void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch);
599static void stl_sc26198rxbadchars(stlport_t *portp);
600static void stl_sc26198otherisr(stlport_t *port, unsigned int iack);
601
602
603
604
605
606
607typedef struct uart {
608 int (*panelinit)(stlbrd_t *brdp, stlpanel_t *panelp);
609 void (*portinit)(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
610 void (*setport)(stlport_t *portp, struct termios *tiosp);
611 int (*getsignals)(stlport_t *portp);
612 void (*setsignals)(stlport_t *portp, int dtr, int rts);
613 void (*enablerxtx)(stlport_t *portp, int rx, int tx);
614 void (*startrxtx)(stlport_t *portp, int rx, int tx);
615 void (*disableintrs)(stlport_t *portp);
616 void (*sendbreak)(stlport_t *portp, int len);
617 void (*flowctrl)(stlport_t *portp, int state);
618 void (*sendflow)(stlport_t *portp, int state);
619 void (*flush)(stlport_t *portp);
620 int (*datastate)(stlport_t *portp);
621 void (*intr)(stlpanel_t *panelp, unsigned int iobase);
622} uart_t;
623
624
625
626
627#define stl_panelinit (* ((uart_t *) panelp->uartp)->panelinit)
628#define stl_portinit (* ((uart_t *) portp->uartp)->portinit)
629#define stl_setport (* ((uart_t *) portp->uartp)->setport)
630#define stl_getsignals (* ((uart_t *) portp->uartp)->getsignals)
631#define stl_setsignals (* ((uart_t *) portp->uartp)->setsignals)
632#define stl_enablerxtx (* ((uart_t *) portp->uartp)->enablerxtx)
633#define stl_startrxtx (* ((uart_t *) portp->uartp)->startrxtx)
634#define stl_disableintrs (* ((uart_t *) portp->uartp)->disableintrs)
635#define stl_sendbreak (* ((uart_t *) portp->uartp)->sendbreak)
636#define stl_flowctrl (* ((uart_t *) portp->uartp)->flowctrl)
637#define stl_sendflow (* ((uart_t *) portp->uartp)->sendflow)
638#define stl_flush (* ((uart_t *) portp->uartp)->flush)
639#define stl_datastate (* ((uart_t *) portp->uartp)->datastate)
640
641
642
643
644
645
646static uart_t stl_cd1400uart = {
647 stl_cd1400panelinit,
648 stl_cd1400portinit,
649 stl_cd1400setport,
650 stl_cd1400getsignals,
651 stl_cd1400setsignals,
652 stl_cd1400enablerxtx,
653 stl_cd1400startrxtx,
654 stl_cd1400disableintrs,
655 stl_cd1400sendbreak,
656 stl_cd1400flowctrl,
657 stl_cd1400sendflow,
658 stl_cd1400flush,
659 stl_cd1400datastate,
660 stl_cd1400eiointr
661};
662
663
664
665
666
667#define EREG_ADDR 0
668#define EREG_DATA 4
669#define EREG_RXACK 5
670#define EREG_TXACK 6
671#define EREG_MDACK 7
672
673#define EREG_BANKSIZE 8
674
675#define CD1400_CLK 25000000
676#define CD1400_CLK8M 20000000
677
678
679
680
681
682
683static int stl_cd1400clkdivs[] = {
684 CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4
685};
686
687
688
689
690
691
692static uart_t stl_sc26198uart = {
693 stl_sc26198panelinit,
694 stl_sc26198portinit,
695 stl_sc26198setport,
696 stl_sc26198getsignals,
697 stl_sc26198setsignals,
698 stl_sc26198enablerxtx,
699 stl_sc26198startrxtx,
700 stl_sc26198disableintrs,
701 stl_sc26198sendbreak,
702 stl_sc26198flowctrl,
703 stl_sc26198sendflow,
704 stl_sc26198flush,
705 stl_sc26198datastate,
706 stl_sc26198intr
707};
708
709
710
711
712#define XP_DATA 0
713#define XP_ADDR 1
714#define XP_MODID 2
715#define XP_STATUS 2
716#define XP_IACK 3
717
718#define XP_BANKSIZE 4
719
720
721
722
723
724static unsigned int sc26198_baudtable[] = {
725 50, 75, 150, 200, 300, 450, 600, 900, 1200, 1800, 2400, 3600,
726 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200,
727 230400, 460800, 921600
728};
729
730#define SC26198_NRBAUDS (sizeof(sc26198_baudtable) / sizeof(unsigned int))
731
732
733
734
735
736
737
738static struct file_operations stl_fsiomem = {
739 owner: THIS_MODULE,
740 ioctl: stl_memioctl,
741};
742
743
744
745static devfs_handle_t devfs_handle;
746
747#ifdef MODULE
748
749
750
751
752
753int init_module()
754{
755 unsigned long flags;
756
757#if DEBUG
758 printk("init_module()\n");
759#endif
760
761 save_flags(flags);
762 cli();
763 stl_init();
764 restore_flags(flags);
765
766 return(0);
767}
768
769
770
771void cleanup_module()
772{
773 stlbrd_t *brdp;
774 stlpanel_t *panelp;
775 stlport_t *portp;
776 unsigned long flags;
777 int i, j, k;
778
779#if DEBUG
780 printk("cleanup_module()\n");
781#endif
782
783 printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle,
784 stl_drvversion);
785
786 save_flags(flags);
787 cli();
788
789
790
791
792
793
794
795 i = tty_unregister_driver(&stl_serial);
796 j = tty_unregister_driver(&stl_callout);
797 if (i || j) {
798 printk("STALLION: failed to un-register tty driver, "
799 "errno=%d,%d\n", -i, -j);
800 restore_flags(flags);
801 return;
802 }
803 devfs_unregister (devfs_handle);
804 if ((i = devfs_unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
805 printk("STALLION: failed to un-register serial memory device, "
806 "errno=%d\n", -i);
807
808 if (stl_tmpwritebuf != (char *) NULL)
809 kfree(stl_tmpwritebuf);
810
811 for (i = 0; (i < stl_nrbrds); i++) {
812 if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
813 continue;
814 for (j = 0; (j < STL_MAXPANELS); j++) {
815 panelp = brdp->panels[j];
816 if (panelp == (stlpanel_t *) NULL)
817 continue;
818 for (k = 0; (k < STL_PORTSPERPANEL); k++) {
819 portp = panelp->ports[k];
820 if (portp == (stlport_t *) NULL)
821 continue;
822 if (portp->tty != (struct tty_struct *) NULL)
823 stl_hangup(portp->tty);
824 if (portp->tx.buf != (char *) NULL)
825 kfree(portp->tx.buf);
826 kfree(portp);
827 }
828 kfree(panelp);
829 }
830 free_irq(brdp->irq, brdp);
831
832 release_region(brdp->ioaddr1, brdp->iosize1);
833 if (brdp->iosize2 > 0)
834 release_region(brdp->ioaddr2, brdp->iosize2);
835
836 kfree(brdp);
837 stl_brds[i] = (stlbrd_t *) NULL;
838 }
839 restore_flags(flags);
840}
841
842
843
844
845
846
847
848static void stl_argbrds()
849{
850 stlconf_t conf;
851 stlbrd_t *brdp;
852 int nrargs, i;
853
854#if DEBUG
855 printk("stl_argbrds()\n");
856#endif
857
858 nrargs = sizeof(stl_brdsp) / sizeof(char **);
859
860 for (i = stl_nrbrds; (i < nrargs); i++) {
861 memset(&conf, 0, sizeof(conf));
862 if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
863 continue;
864 if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
865 continue;
866 stl_nrbrds = i + 1;
867 brdp->brdnr = i;
868 brdp->brdtype = conf.brdtype;
869 brdp->ioaddr1 = conf.ioaddr1;
870 brdp->ioaddr2 = conf.ioaddr2;
871 brdp->irq = conf.irq;
872 brdp->irqtype = conf.irqtype;
873 stl_brdinit(brdp);
874 }
875}
876
877
878
879
880
881
882
883static unsigned long stl_atol(char *str)
884{
885 unsigned long val;
886 int base, c;
887 char *sp;
888
889 val = 0;
890 sp = str;
891 if ((*sp == '0') && (*(sp+1) == 'x')) {
892 base = 16;
893 sp += 2;
894 } else if (*sp == '0') {
895 base = 8;
896 sp++;
897 } else {
898 base = 10;
899 }
900
901 for (; (*sp != 0); sp++) {
902 c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
903 if ((c < 0) || (c >= base)) {
904 printk("STALLION: invalid argument %s\n", str);
905 val = 0;
906 break;
907 }
908 val = (val * base) + c;
909 }
910 return(val);
911}
912
913
914
915
916
917
918
919static int stl_parsebrd(stlconf_t *confp, char **argp)
920{
921 char *sp;
922 int nrbrdnames, i;
923
924#if DEBUG
925 printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
926#endif
927
928 if ((argp[0] == (char *) NULL) || (*argp[0] == 0))
929 return(0);
930
931 for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
932 *sp = TOLOWER(*sp);
933
934 nrbrdnames = sizeof(stl_brdstr) / sizeof(stlbrdtype_t);
935 for (i = 0; (i < nrbrdnames); i++) {
936 if (strcmp(stl_brdstr[i].name, argp[0]) == 0)
937 break;
938 }
939 if (i >= nrbrdnames) {
940 printk("STALLION: unknown board name, %s?\n", argp[0]);
941 return(0);
942 }
943
944 confp->brdtype = stl_brdstr[i].type;
945
946 i = 1;
947 if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
948 confp->ioaddr1 = stl_atol(argp[i]);
949 i++;
950 if (confp->brdtype == BRD_ECH) {
951 if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
952 confp->ioaddr2 = stl_atol(argp[i]);
953 i++;
954 }
955 if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
956 confp->irq = stl_atol(argp[i]);
957 return(1);
958}
959
960#endif
961
962
963
964
965
966
967
968static void *stl_memalloc(int len)
969{
970 return((void *) kmalloc(len, GFP_KERNEL));
971}
972
973
974
975
976
977
978
979static stlbrd_t *stl_allocbrd()
980{
981 stlbrd_t *brdp;
982
983 brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
984 if (brdp == (stlbrd_t *) NULL) {
985 printk("STALLION: failed to allocate memory (size=%d)\n",
986 sizeof(stlbrd_t));
987 return((stlbrd_t *) NULL);
988 }
989
990 memset(brdp, 0, sizeof(stlbrd_t));
991 brdp->magic = STL_BOARDMAGIC;
992 return(brdp);
993}
994
995
996
997static int stl_open(struct tty_struct *tty, struct file *filp)
998{
999 stlport_t *portp;
1000 stlbrd_t *brdp;
1001 unsigned int minordev;
1002 int brdnr, panelnr, portnr, rc;
1003
1004#if DEBUG
1005 printk("stl_open(tty=%x,filp=%x): device=%x\n", (int) tty,
1006 (int) filp, tty->device);
1007#endif
1008
1009 minordev = MINOR(tty->device);
1010 brdnr = MINOR2BRD(minordev);
1011 if (brdnr >= stl_nrbrds)
1012 return(-ENODEV);
1013 brdp = stl_brds[brdnr];
1014 if (brdp == (stlbrd_t *) NULL)
1015 return(-ENODEV);
1016 minordev = MINOR2PORT(minordev);
1017 for (portnr = -1, panelnr = 0; (panelnr < STL_MAXPANELS); panelnr++) {
1018 if (brdp->panels[panelnr] == (stlpanel_t *) NULL)
1019 break;
1020 if (minordev < brdp->panels[panelnr]->nrports) {
1021 portnr = minordev;
1022 break;
1023 }
1024 minordev -= brdp->panels[panelnr]->nrports;
1025 }
1026 if (portnr < 0)
1027 return(-ENODEV);
1028
1029 portp = brdp->panels[panelnr]->ports[portnr];
1030 if (portp == (stlport_t *) NULL)
1031 return(-ENODEV);
1032
1033 MOD_INC_USE_COUNT;
1034
1035
1036
1037
1038
1039 portp->tty = tty;
1040 tty->driver_data = portp;
1041 portp->refcount++;
1042
1043 if ((portp->flags & ASYNC_INITIALIZED) == 0) {
1044 if (portp->tx.buf == (char *) NULL) {
1045 portp->tx.buf = (char *) stl_memalloc(STL_TXBUFSIZE);
1046 if (portp->tx.buf == (char *) NULL)
1047 return(-ENOMEM);
1048 portp->tx.head = portp->tx.buf;
1049 portp->tx.tail = portp->tx.buf;
1050 }
1051 stl_setport(portp, tty->termios);
1052 portp->sigs = stl_getsignals(portp);
1053 stl_setsignals(portp, 1, 1);
1054 stl_enablerxtx(portp, 1, 1);
1055 stl_startrxtx(portp, 1, 0);
1056 clear_bit(TTY_IO_ERROR, &tty->flags);
1057 portp->flags |= ASYNC_INITIALIZED;
1058 }
1059
1060
1061
1062
1063
1064
1065
1066 if (portp->flags & ASYNC_CLOSING) {
1067 interruptible_sleep_on(&portp->close_wait);
1068 if (portp->flags & ASYNC_HUP_NOTIFY)
1069 return(-EAGAIN);
1070 return(-ERESTARTSYS);
1071 }
1072
1073
1074
1075
1076
1077
1078 if (tty->driver.subtype == STL_DRVTYPCALLOUT) {
1079 if (portp->flags & ASYNC_NORMAL_ACTIVE)
1080 return(-EBUSY);
1081 if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
1082 if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
1083 (portp->session != current->session))
1084 return(-EBUSY);
1085 if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
1086 (portp->pgrp != current->pgrp))
1087 return(-EBUSY);
1088 }
1089 portp->flags |= ASYNC_CALLOUT_ACTIVE;
1090 } else {
1091 if (filp->f_flags & O_NONBLOCK) {
1092 if (portp->flags & ASYNC_CALLOUT_ACTIVE)
1093 return(-EBUSY);
1094 } else {
1095 if ((rc = stl_waitcarrier(portp, filp)) != 0)
1096 return(rc);
1097 }
1098 portp->flags |= ASYNC_NORMAL_ACTIVE;
1099 }
1100
1101 if ((portp->refcount == 1) && (portp->flags & ASYNC_SPLIT_TERMIOS)) {
1102 if (tty->driver.subtype == STL_DRVTYPSERIAL)
1103 *tty->termios = portp->normaltermios;
1104 else
1105 *tty->termios = portp->callouttermios;
1106 stl_setport(portp, tty->termios);
1107 }
1108
1109 portp->session = current->session;
1110 portp->pgrp = current->pgrp;
1111 return(0);
1112}
1113
1114
1115
1116
1117
1118
1119
1120
1121static int stl_waitcarrier(stlport_t *portp, struct file *filp)
1122{
1123 unsigned long flags;
1124 int rc, doclocal;
1125
1126#if DEBUG
1127 printk("stl_waitcarrier(portp=%x,filp=%x)\n", (int) portp, (int) filp);
1128#endif
1129
1130 rc = 0;
1131 doclocal = 0;
1132
1133 if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
1134 if (portp->normaltermios.c_cflag & CLOCAL)
1135 doclocal++;
1136 } else {
1137 if (portp->tty->termios->c_cflag & CLOCAL)
1138 doclocal++;
1139 }
1140
1141 save_flags(flags);
1142 cli();
1143 portp->openwaitcnt++;
1144 if (! tty_hung_up_p(filp))
1145 portp->refcount--;
1146
1147 for (;;) {
1148 if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0)
1149 stl_setsignals(portp, 1, 1);
1150 if (tty_hung_up_p(filp) ||
1151 ((portp->flags & ASYNC_INITIALIZED) == 0)) {
1152 if (portp->flags & ASYNC_HUP_NOTIFY)
1153 rc = -EBUSY;
1154 else
1155 rc = -ERESTARTSYS;
1156 break;
1157 }
1158 if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
1159 ((portp->flags & ASYNC_CLOSING) == 0) &&
1160 (doclocal || (portp->sigs & TIOCM_CD))) {
1161 break;
1162 }
1163 if (signal_pending(current)) {
1164 rc = -ERESTARTSYS;
1165 break;
1166 }
1167 interruptible_sleep_on(&portp->open_wait);
1168 }
1169
1170 if (! tty_hung_up_p(filp))
1171 portp->refcount++;
1172 portp->openwaitcnt--;
1173 restore_flags(flags);
1174
1175 return(rc);
1176}
1177
1178
1179
1180static void stl_close(struct tty_struct *tty, struct file *filp)
1181{
1182 stlport_t *portp;
1183 unsigned long flags;
1184
1185#if DEBUG
1186 printk("stl_close(tty=%x,filp=%x)\n", (int) tty, (int) filp);
1187#endif
1188
1189 portp = tty->driver_data;
1190 if (portp == (stlport_t *) NULL)
1191 return;
1192
1193 save_flags(flags);
1194 cli();
1195 if (tty_hung_up_p(filp)) {
1196 MOD_DEC_USE_COUNT;
1197 restore_flags(flags);
1198 return;
1199 }
1200 if ((tty->count == 1) && (portp->refcount != 1))
1201 portp->refcount = 1;
1202 if (portp->refcount-- > 1) {
1203 MOD_DEC_USE_COUNT;
1204 restore_flags(flags);
1205 return;
1206 }
1207
1208 portp->refcount = 0;
1209 portp->flags |= ASYNC_CLOSING;
1210
1211 if (portp->flags & ASYNC_NORMAL_ACTIVE)
1212 portp->normaltermios = *tty->termios;
1213 if (portp->flags & ASYNC_CALLOUT_ACTIVE)
1214 portp->callouttermios = *tty->termios;
1215
1216
1217
1218
1219
1220
1221
1222 tty->closing = 1;
1223 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1224 tty_wait_until_sent(tty, portp->closing_wait);
1225 stl_waituntilsent(tty, (HZ / 2));
1226
1227 portp->flags &= ~ASYNC_INITIALIZED;
1228 stl_disableintrs(portp);
1229 if (tty->termios->c_cflag & HUPCL)
1230 stl_setsignals(portp, 0, 0);
1231 stl_enablerxtx(portp, 0, 0);
1232 stl_flushbuffer(tty);
1233 portp->istate = 0;
1234 if (portp->tx.buf != (char *) NULL) {
1235 kfree(portp->tx.buf);
1236 portp->tx.buf = (char *) NULL;
1237 portp->tx.head = (char *) NULL;
1238 portp->tx.tail = (char *) NULL;
1239 }
1240 set_bit(TTY_IO_ERROR, &tty->flags);
1241 tty_ldisc_flush(tty);
1242
1243 tty->closing = 0;
1244 portp->tty = (struct tty_struct *) NULL;
1245
1246 if (portp->openwaitcnt) {
1247 if (portp->close_delay)
1248 stl_delay(portp->close_delay);
1249 wake_up_interruptible(&portp->open_wait);
1250 }
1251
1252 portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE |
1253 ASYNC_CLOSING);
1254 wake_up_interruptible(&portp->close_wait);
1255 MOD_DEC_USE_COUNT;
1256 restore_flags(flags);
1257}
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267static void stl_delay(int len)
1268{
1269#if DEBUG
1270 printk("stl_delay(len=%d)\n", len);
1271#endif
1272 if (len > 0) {
1273 current->state = TASK_INTERRUPTIBLE;
1274 schedule_timeout(len);
1275 current->state = TASK_RUNNING;
1276 }
1277}
1278
1279
1280
1281
1282
1283
1284
1285
1286static int stl_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
1287{
1288 stlport_t *portp;
1289 unsigned int len, stlen;
1290 unsigned char *chbuf;
1291 char *head, *tail;
1292
1293#if DEBUG
1294 printk("stl_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
1295 (int) tty, from_user, (int) buf, count);
1296#endif
1297
1298 if ((tty == (struct tty_struct *) NULL) ||
1299 (stl_tmpwritebuf == (char *) NULL))
1300 return(0);
1301 portp = tty->driver_data;
1302 if (portp == (stlport_t *) NULL)
1303 return(0);
1304 if (portp->tx.buf == (char *) NULL)
1305 return(0);
1306
1307
1308
1309
1310
1311
1312
1313 chbuf = (unsigned char *) buf;
1314 if (from_user) {
1315 head = portp->tx.head;
1316 tail = portp->tx.tail;
1317 len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) :
1318 (tail - head - 1);
1319 count = MIN(len, count);
1320
1321 down(&stl_tmpwritesem);
1322 copy_from_user(stl_tmpwritebuf, chbuf, count);
1323 chbuf = &stl_tmpwritebuf[0];
1324 }
1325
1326 head = portp->tx.head;
1327 tail = portp->tx.tail;
1328 if (head >= tail) {
1329 len = STL_TXBUFSIZE - (head - tail) - 1;
1330 stlen = STL_TXBUFSIZE - (head - portp->tx.buf);
1331 } else {
1332 len = tail - head - 1;
1333 stlen = len;
1334 }
1335
1336 len = MIN(len, count);
1337 count = 0;
1338 while (len > 0) {
1339 stlen = MIN(len, stlen);
1340 memcpy(head, chbuf, stlen);
1341 len -= stlen;
1342 chbuf += stlen;
1343 count += stlen;
1344 head += stlen;
1345 if (head >= (portp->tx.buf + STL_TXBUFSIZE)) {
1346 head = portp->tx.buf;
1347 stlen = tail - head;
1348 }
1349 }
1350 portp->tx.head = head;
1351
1352 clear_bit(ASYI_TXLOW, &portp->istate);
1353 stl_startrxtx(portp, -1, 1);
1354
1355 if (from_user)
1356 up(&stl_tmpwritesem);
1357
1358 return(count);
1359}
1360
1361
1362
1363static void stl_putchar(struct tty_struct *tty, unsigned char ch)
1364{
1365 stlport_t *portp;
1366 unsigned int len;
1367 char *head, *tail;
1368
1369#if DEBUG
1370 printk("stl_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch);
1371#endif
1372
1373 if (tty == (struct tty_struct *) NULL)
1374 return;
1375 portp = tty->driver_data;
1376 if (portp == (stlport_t *) NULL)
1377 return;
1378 if (portp->tx.buf == (char *) NULL)
1379 return;
1380
1381 head = portp->tx.head;
1382 tail = portp->tx.tail;
1383
1384 len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail)) : (tail - head);
1385 len--;
1386
1387 if (len > 0) {
1388 *head++ = ch;
1389 if (head >= (portp->tx.buf + STL_TXBUFSIZE))
1390 head = portp->tx.buf;
1391 }
1392 portp->tx.head = head;
1393}
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403static void stl_flushchars(struct tty_struct *tty)
1404{
1405 stlport_t *portp;
1406
1407#if DEBUG
1408 printk("stl_flushchars(tty=%x)\n", (int) tty);
1409#endif
1410
1411 if (tty == (struct tty_struct *) NULL)
1412 return;
1413 portp = tty->driver_data;
1414 if (portp == (stlport_t *) NULL)
1415 return;
1416 if (portp->tx.buf == (char *) NULL)
1417 return;
1418
1419#if 0
1420 if (tty->stopped || tty->hw_stopped ||
1421 (portp->tx.head == portp->tx.tail))
1422 return;
1423#endif
1424 stl_startrxtx(portp, -1, 1);
1425}
1426
1427
1428
1429static int stl_writeroom(struct tty_struct *tty)
1430{
1431 stlport_t *portp;
1432 char *head, *tail;
1433
1434#if DEBUG
1435 printk("stl_writeroom(tty=%x)\n", (int) tty);
1436#endif
1437
1438 if (tty == (struct tty_struct *) NULL)
1439 return(0);
1440 portp = tty->driver_data;
1441 if (portp == (stlport_t *) NULL)
1442 return(0);
1443 if (portp->tx.buf == (char *) NULL)
1444 return(0);
1445
1446 head = portp->tx.head;
1447 tail = portp->tx.tail;
1448 return((head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1));
1449}
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462static int stl_charsinbuffer(struct tty_struct *tty)
1463{
1464 stlport_t *portp;
1465 unsigned int size;
1466 char *head, *tail;
1467
1468#if DEBUG
1469 printk("stl_charsinbuffer(tty=%x)\n", (int) tty);
1470#endif
1471
1472 if (tty == (struct tty_struct *) NULL)
1473 return(0);
1474 portp = tty->driver_data;
1475 if (portp == (stlport_t *) NULL)
1476 return(0);
1477 if (portp->tx.buf == (char *) NULL)
1478 return(0);
1479
1480 head = portp->tx.head;
1481 tail = portp->tx.tail;
1482 size = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
1483 if ((size == 0) && test_bit(ASYI_TXBUSY, &portp->istate))
1484 size = 1;
1485 return(size);
1486}
1487
1488
1489
1490
1491
1492
1493
1494static void stl_getserial(stlport_t *portp, struct serial_struct *sp)
1495{
1496 struct serial_struct sio;
1497 stlbrd_t *brdp;
1498
1499#if DEBUG
1500 printk("stl_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
1501#endif
1502
1503 memset(&sio, 0, sizeof(struct serial_struct));
1504 sio.line = portp->portnr;
1505 sio.port = portp->ioaddr;
1506 sio.flags = portp->flags;
1507 sio.baud_base = portp->baud_base;
1508 sio.close_delay = portp->close_delay;
1509 sio.closing_wait = portp->closing_wait;
1510 sio.custom_divisor = portp->custom_divisor;
1511 sio.hub6 = 0;
1512 if (portp->uartp == &stl_cd1400uart) {
1513 sio.type = PORT_CIRRUS;
1514 sio.xmit_fifo_size = CD1400_TXFIFOSIZE;
1515 } else {
1516 sio.type = PORT_UNKNOWN;
1517 sio.xmit_fifo_size = SC26198_TXFIFOSIZE;
1518 }
1519
1520 brdp = stl_brds[portp->brdnr];
1521 if (brdp != (stlbrd_t *) NULL)
1522 sio.irq = brdp->irq;
1523
1524 copy_to_user(sp, &sio, sizeof(struct serial_struct));
1525}
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535static int stl_setserial(stlport_t *portp, struct serial_struct *sp)
1536{
1537 struct serial_struct sio;
1538
1539#if DEBUG
1540 printk("stl_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
1541#endif
1542
1543 if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
1544 return -EFAULT;
1545 if (!capable(CAP_SYS_ADMIN)) {
1546 if ((sio.baud_base != portp->baud_base) ||
1547 (sio.close_delay != portp->close_delay) ||
1548 ((sio.flags & ~ASYNC_USR_MASK) !=
1549 (portp->flags & ~ASYNC_USR_MASK)))
1550 return(-EPERM);
1551 }
1552
1553 portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
1554 (sio.flags & ASYNC_USR_MASK);
1555 portp->baud_base = sio.baud_base;
1556 portp->close_delay = sio.close_delay;
1557 portp->closing_wait = sio.closing_wait;
1558 portp->custom_divisor = sio.custom_divisor;
1559 stl_setport(portp, portp->tty->termios);
1560 return(0);
1561}
1562
1563
1564
1565static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1566{
1567 stlport_t *portp;
1568 unsigned int ival;
1569 int rc;
1570
1571#if DEBUG
1572 printk("stl_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
1573 (int) tty, (int) file, cmd, (int) arg);
1574#endif
1575
1576 if (tty == (struct tty_struct *) NULL)
1577 return(-ENODEV);
1578 portp = tty->driver_data;
1579 if (portp == (stlport_t *) NULL)
1580 return(-ENODEV);
1581
1582 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1583 (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
1584 if (tty->flags & (1 << TTY_IO_ERROR))
1585 return(-EIO);
1586 }
1587
1588 rc = 0;
1589
1590 switch (cmd) {
1591 case TIOCGSOFTCAR:
1592 rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
1593 (unsigned int *) arg);
1594 break;
1595 case TIOCSSOFTCAR:
1596 if ((rc = verify_area(VERIFY_READ, (void *) arg,
1597 sizeof(int))) == 0) {
1598 get_user(ival, (unsigned int *) arg);
1599 tty->termios->c_cflag =
1600 (tty->termios->c_cflag & ~CLOCAL) |
1601 (ival ? CLOCAL : 0);
1602 }
1603 break;
1604 case TIOCMGET:
1605 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
1606 sizeof(unsigned int))) == 0) {
1607 ival = stl_getsignals(portp);
1608 put_user(ival, (unsigned int *) arg);
1609 }
1610 break;
1611 case TIOCMBIS:
1612 if ((rc = verify_area(VERIFY_READ, (void *) arg,
1613 sizeof(unsigned int))) == 0) {
1614 get_user(ival, (unsigned int *) arg);
1615 stl_setsignals(portp, ((ival & TIOCM_DTR) ? 1 : -1),
1616 ((ival & TIOCM_RTS) ? 1 : -1));
1617 }
1618 break;
1619 case TIOCMBIC:
1620 if ((rc = verify_area(VERIFY_READ, (void *) arg,
1621 sizeof(unsigned int))) == 0) {
1622 get_user(ival, (unsigned int *) arg);
1623 stl_setsignals(portp, ((ival & TIOCM_DTR) ? 0 : -1),
1624 ((ival & TIOCM_RTS) ? 0 : -1));
1625 }
1626 break;
1627 case TIOCMSET:
1628 if ((rc = verify_area(VERIFY_READ, (void *) arg,
1629 sizeof(unsigned int))) == 0) {
1630 get_user(ival, (unsigned int *) arg);
1631 stl_setsignals(portp, ((ival & TIOCM_DTR) ? 1 : 0),
1632 ((ival & TIOCM_RTS) ? 1 : 0));
1633 }
1634 break;
1635 case TIOCGSERIAL:
1636 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
1637 sizeof(struct serial_struct))) == 0)
1638 stl_getserial(portp, (struct serial_struct *) arg);
1639 break;
1640 case TIOCSSERIAL:
1641 if ((rc = verify_area(VERIFY_READ, (void *) arg,
1642 sizeof(struct serial_struct))) == 0)
1643 rc = stl_setserial(portp, (struct serial_struct *) arg);
1644 break;
1645 case COM_GETPORTSTATS:
1646 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
1647 sizeof(comstats_t))) == 0)
1648 rc = stl_getportstats(portp, (comstats_t *) arg);
1649 break;
1650 case COM_CLRPORTSTATS:
1651 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
1652 sizeof(comstats_t))) == 0)
1653 rc = stl_clrportstats(portp, (comstats_t *) arg);
1654 break;
1655 case TIOCSERCONFIG:
1656 case TIOCSERGWILD:
1657 case TIOCSERSWILD:
1658 case TIOCSERGETLSR:
1659 case TIOCSERGSTRUCT:
1660 case TIOCSERGETMULTI:
1661 case TIOCSERSETMULTI:
1662 default:
1663 rc = -ENOIOCTLCMD;
1664 break;
1665 }
1666
1667 return(rc);
1668}
1669
1670
1671
1672static void stl_settermios(struct tty_struct *tty, struct termios *old)
1673{
1674 stlport_t *portp;
1675 struct termios *tiosp;
1676
1677#if DEBUG
1678 printk("stl_settermios(tty=%x,old=%x)\n", (int) tty, (int) old);
1679#endif
1680
1681 if (tty == (struct tty_struct *) NULL)
1682 return;
1683 portp = tty->driver_data;
1684 if (portp == (stlport_t *) NULL)
1685 return;
1686
1687 tiosp = tty->termios;
1688 if ((tiosp->c_cflag == old->c_cflag) &&
1689 (tiosp->c_iflag == old->c_iflag))
1690 return;
1691
1692 stl_setport(portp, tiosp);
1693 stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0),
1694 -1);
1695 if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) {
1696 tty->hw_stopped = 0;
1697 stl_start(tty);
1698 }
1699 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
1700 wake_up_interruptible(&portp->open_wait);
1701}
1702
1703
1704
1705
1706
1707
1708
1709
1710static void stl_throttle(struct tty_struct *tty)
1711{
1712 stlport_t *portp;
1713
1714#if DEBUG
1715 printk("stl_throttle(tty=%x)\n", (int) tty);
1716#endif
1717
1718 if (tty == (struct tty_struct *) NULL)
1719 return;
1720 portp = tty->driver_data;
1721 if (portp == (stlport_t *) NULL)
1722 return;
1723 stl_flowctrl(portp, 0);
1724}
1725
1726
1727
1728
1729
1730
1731
1732static void stl_unthrottle(struct tty_struct *tty)
1733{
1734 stlport_t *portp;
1735
1736#if DEBUG
1737 printk("stl_unthrottle(tty=%x)\n", (int) tty);
1738#endif
1739
1740 if (tty == (struct tty_struct *) NULL)
1741 return;
1742 portp = tty->driver_data;
1743 if (portp == (stlport_t *) NULL)
1744 return;
1745 stl_flowctrl(portp, 1);
1746}
1747
1748
1749
1750
1751
1752
1753
1754
1755static void stl_stop(struct tty_struct *tty)
1756{
1757 stlport_t *portp;
1758
1759#if DEBUG
1760 printk("stl_stop(tty=%x)\n", (int) tty);
1761#endif
1762
1763 if (tty == (struct tty_struct *) NULL)
1764 return;
1765 portp = tty->driver_data;
1766 if (portp == (stlport_t *) NULL)
1767 return;
1768 stl_startrxtx(portp, -1, 0);
1769}
1770
1771
1772
1773
1774
1775
1776
1777static void stl_start(struct tty_struct *tty)
1778{
1779 stlport_t *portp;
1780
1781#if DEBUG
1782 printk("stl_start(tty=%x)\n", (int) tty);
1783#endif
1784
1785 if (tty == (struct tty_struct *) NULL)
1786 return;
1787 portp = tty->driver_data;
1788 if (portp == (stlport_t *) NULL)
1789 return;
1790 stl_startrxtx(portp, -1, 1);
1791}
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801static void stl_hangup(struct tty_struct *tty)
1802{
1803 stlport_t *portp;
1804
1805#if DEBUG
1806 printk("stl_hangup(tty=%x)\n", (int) tty);
1807#endif
1808
1809 if (tty == (struct tty_struct *) NULL)
1810 return;
1811 portp = tty->driver_data;
1812 if (portp == (stlport_t *) NULL)
1813 return;
1814
1815 portp->flags &= ~ASYNC_INITIALIZED;
1816 stl_disableintrs(portp);
1817 if (tty->termios->c_cflag & HUPCL)
1818 stl_setsignals(portp, 0, 0);
1819 stl_enablerxtx(portp, 0, 0);
1820 stl_flushbuffer(tty);
1821 portp->istate = 0;
1822 set_bit(TTY_IO_ERROR, &tty->flags);
1823 if (portp->tx.buf != (char *) NULL) {
1824 kfree(portp->tx.buf);
1825 portp->tx.buf = (char *) NULL;
1826 portp->tx.head = (char *) NULL;
1827 portp->tx.tail = (char *) NULL;
1828 }
1829 portp->tty = (struct tty_struct *) NULL;
1830 portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
1831 portp->refcount = 0;
1832 wake_up_interruptible(&portp->open_wait);
1833}
1834
1835
1836
1837static void stl_flushbuffer(struct tty_struct *tty)
1838{
1839 stlport_t *portp;
1840
1841#if DEBUG
1842 printk("stl_flushbuffer(tty=%x)\n", (int) tty);
1843#endif
1844
1845 if (tty == (struct tty_struct *) NULL)
1846 return;
1847 portp = tty->driver_data;
1848 if (portp == (stlport_t *) NULL)
1849 return;
1850
1851 stl_flush(portp);
1852 tty_wakeup(tty);
1853}
1854
1855
1856
1857static void stl_breakctl(struct tty_struct *tty, int state)
1858{
1859 stlport_t *portp;
1860
1861#if DEBUG
1862 printk("stl_breakctl(tty=%x,state=%d)\n", (int) tty, state);
1863#endif
1864
1865 if (tty == (struct tty_struct *) NULL)
1866 return;
1867 portp = tty->driver_data;
1868 if (portp == (stlport_t *) NULL)
1869 return;
1870
1871 stl_sendbreak(portp, ((state == -1) ? 1 : 2));
1872}
1873
1874
1875
1876static void stl_waituntilsent(struct tty_struct *tty, int timeout)
1877{
1878 stlport_t *portp;
1879 unsigned long tend;
1880
1881#if DEBUG
1882 printk("stl_waituntilsent(tty=%x,timeout=%d)\n", (int) tty, timeout);
1883#endif
1884
1885 if (tty == (struct tty_struct *) NULL)
1886 return;
1887 portp = tty->driver_data;
1888 if (portp == (stlport_t *) NULL)
1889 return;
1890
1891 if (timeout == 0)
1892 timeout = HZ;
1893 tend = jiffies + timeout;
1894
1895 while (stl_datastate(portp)) {
1896 if (signal_pending(current))
1897 break;
1898 stl_delay(2);
1899 if (time_after_eq(jiffies, tend))
1900 break;
1901 }
1902}
1903
1904
1905
1906static void stl_sendxchar(struct tty_struct *tty, char ch)
1907{
1908 stlport_t *portp;
1909
1910#if DEBUG
1911 printk("stl_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch);
1912#endif
1913
1914 if (tty == (struct tty_struct *) NULL)
1915 return;
1916 portp = tty->driver_data;
1917 if (portp == (stlport_t *) NULL)
1918 return;
1919
1920 if (ch == STOP_CHAR(tty))
1921 stl_sendflow(portp, 0);
1922 else if (ch == START_CHAR(tty))
1923 stl_sendflow(portp, 1);
1924 else
1925 stl_putchar(tty, ch);
1926}
1927
1928
1929
1930#define MAXLINE 80
1931
1932
1933
1934
1935
1936
1937
1938static int stl_portinfo(stlport_t *portp, int portnr, char *pos)
1939{
1940 char *sp;
1941 int sigs, cnt;
1942
1943 sp = pos;
1944 sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
1945 portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
1946 (int) portp->stats.txtotal, (int) portp->stats.rxtotal);
1947
1948 if (portp->stats.rxframing)
1949 sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
1950 if (portp->stats.rxparity)
1951 sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
1952 if (portp->stats.rxbreaks)
1953 sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
1954 if (portp->stats.rxoverrun)
1955 sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
1956
1957 sigs = stl_getsignals(portp);
1958 cnt = sprintf(sp, "%s%s%s%s%s ",
1959 (sigs & TIOCM_RTS) ? "|RTS" : "",
1960 (sigs & TIOCM_CTS) ? "|CTS" : "",
1961 (sigs & TIOCM_DTR) ? "|DTR" : "",
1962 (sigs & TIOCM_CD) ? "|DCD" : "",
1963 (sigs & TIOCM_DSR) ? "|DSR" : "");
1964 *sp = ' ';
1965 sp += cnt;
1966
1967 for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
1968 *sp++ = ' ';
1969 if (cnt >= MAXLINE)
1970 pos[(MAXLINE - 2)] = '+';
1971 pos[(MAXLINE - 1)] = '\n';
1972
1973 return(MAXLINE);
1974}
1975
1976
1977
1978
1979
1980
1981
1982static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
1983{
1984 stlbrd_t *brdp;
1985 stlpanel_t *panelp;
1986 stlport_t *portp;
1987 int brdnr, panelnr, portnr, totalport;
1988 int curoff, maxoff;
1989 char *pos;
1990
1991#if DEBUG
1992 printk("stl_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x,"
1993 "data=%x\n", (int) page, (int) start, (int) off, count,
1994 (int) eof, (int) data);
1995#endif
1996
1997 pos = page;
1998 totalport = 0;
1999 curoff = 0;
2000
2001 if (off == 0) {
2002 pos += sprintf(pos, "%s: version %s", stl_drvtitle,
2003 stl_drvversion);
2004 while (pos < (page + MAXLINE - 1))
2005 *pos++ = ' ';
2006 *pos++ = '\n';
2007 }
2008 curoff = MAXLINE;
2009
2010
2011
2012
2013
2014 for (brdnr = 0; (brdnr < stl_nrbrds); brdnr++) {
2015 brdp = stl_brds[brdnr];
2016 if (brdp == (stlbrd_t *) NULL)
2017 continue;
2018 if (brdp->state == 0)
2019 continue;
2020
2021 maxoff = curoff + (brdp->nrports * MAXLINE);
2022 if (off >= maxoff) {
2023 curoff = maxoff;
2024 continue;
2025 }
2026
2027 totalport = brdnr * STL_MAXPORTS;
2028 for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
2029 panelp = brdp->panels[panelnr];
2030 if (panelp == (stlpanel_t *) NULL)
2031 continue;
2032
2033 maxoff = curoff + (panelp->nrports * MAXLINE);
2034 if (off >= maxoff) {
2035 curoff = maxoff;
2036 totalport += panelp->nrports;
2037 continue;
2038 }
2039
2040 for (portnr = 0; (portnr < panelp->nrports); portnr++,
2041 totalport++) {
2042 portp = panelp->ports[portnr];
2043 if (portp == (stlport_t *) NULL)
2044 continue;
2045 if (off >= (curoff += MAXLINE))
2046 continue;
2047 if ((pos - page + MAXLINE) > count)
2048 goto stl_readdone;
2049 pos += stl_portinfo(portp, totalport, pos);
2050 }
2051 }
2052 }
2053
2054 *eof = 1;
2055
2056stl_readdone:
2057 *start = page;
2058 return(pos - page);
2059}
2060
2061
2062
2063
2064
2065
2066
2067
2068static void stl_intr(int irq, void *dev_id, struct pt_regs *regs)
2069{
2070 stlbrd_t *brdp;
2071
2072#if DEBUG
2073 printk("stl_intr(irq=%d,regs=%x)\n", irq, (int) regs);
2074#endif
2075 brdp = (stlbrd_t *) dev_id;
2076 (* brdp->isr)(brdp);
2077}
2078
2079
2080
2081
2082
2083
2084
2085static void stl_eiointr(stlbrd_t *brdp)
2086{
2087 stlpanel_t *panelp;
2088 unsigned int iobase;
2089
2090 panelp = brdp->panels[0];
2091 iobase = panelp->iobase;
2092 while (inb(brdp->iostatus) & EIO_INTRPEND)
2093 (* panelp->isr)(panelp, iobase);
2094}
2095
2096
2097
2098
2099
2100
2101
2102static void stl_echatintr(stlbrd_t *brdp)
2103{
2104 stlpanel_t *panelp;
2105 unsigned int ioaddr;
2106 int bnknr;
2107
2108 outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
2109
2110 while (inb(brdp->iostatus) & ECH_INTRPEND) {
2111 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
2112 ioaddr = brdp->bnkstataddr[bnknr];
2113 if (inb(ioaddr) & ECH_PNLINTRPEND) {
2114 panelp = brdp->bnk2panel[bnknr];
2115 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
2116 }
2117 }
2118 }
2119
2120 outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
2121}
2122
2123
2124
2125
2126
2127
2128
2129static void stl_echmcaintr(stlbrd_t *brdp)
2130{
2131 stlpanel_t *panelp;
2132 unsigned int ioaddr;
2133 int bnknr;
2134
2135 while (inb(brdp->iostatus) & ECH_INTRPEND) {
2136 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
2137 ioaddr = brdp->bnkstataddr[bnknr];
2138 if (inb(ioaddr) & ECH_PNLINTRPEND) {
2139 panelp = brdp->bnk2panel[bnknr];
2140 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
2141 }
2142 }
2143 }
2144}
2145
2146
2147
2148
2149
2150
2151
2152static void stl_echpciintr(stlbrd_t *brdp)
2153{
2154 stlpanel_t *panelp;
2155 unsigned int ioaddr;
2156 int bnknr, recheck;
2157
2158 while (1) {
2159 recheck = 0;
2160 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
2161 outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl);
2162 ioaddr = brdp->bnkstataddr[bnknr];
2163 if (inb(ioaddr) & ECH_PNLINTRPEND) {
2164 panelp = brdp->bnk2panel[bnknr];
2165 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
2166 recheck++;
2167 }
2168 }
2169 if (! recheck)
2170 break;
2171 }
2172}
2173
2174
2175
2176
2177
2178
2179
2180static void stl_echpci64intr(stlbrd_t *brdp)
2181{
2182 stlpanel_t *panelp;
2183 unsigned int ioaddr;
2184 int bnknr;
2185
2186 while (inb(brdp->ioctrl) & 0x1) {
2187 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
2188 ioaddr = brdp->bnkstataddr[bnknr];
2189 if (inb(ioaddr) & ECH_PNLINTRPEND) {
2190 panelp = brdp->bnk2panel[bnknr];
2191 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
2192 }
2193 }
2194 }
2195}
2196
2197
2198
2199
2200
2201
2202static void stl_offintr(void *private)
2203{
2204 stlport_t *portp;
2205 struct tty_struct *tty;
2206 unsigned int oldsigs;
2207
2208 portp = private;
2209
2210#if DEBUG
2211 printk("stl_offintr(portp=%x)\n", (int) portp);
2212#endif
2213
2214 if (portp == (stlport_t *) NULL)
2215 goto out;
2216
2217 tty = portp->tty;
2218 if (tty == (struct tty_struct *) NULL)
2219 goto out;
2220
2221 lock_kernel();
2222 if (test_bit(ASYI_TXLOW, &portp->istate)) {
2223 tty_wakeup(tty);
2224 }
2225 if (test_bit(ASYI_DCDCHANGE, &portp->istate)) {
2226 clear_bit(ASYI_DCDCHANGE, &portp->istate);
2227 oldsigs = portp->sigs;
2228 portp->sigs = stl_getsignals(portp);
2229 if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
2230 wake_up_interruptible(&portp->open_wait);
2231 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
2232 if (portp->flags & ASYNC_CHECK_CD) {
2233 if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
2234 (portp->flags & ASYNC_CALLOUT_NOHUP))) {
2235 tty_hangup(tty);
2236 }
2237 }
2238 }
2239 }
2240 unlock_kernel();
2241out:
2242 MOD_DEC_USE_COUNT;
2243}
2244
2245
2246
2247
2248
2249
2250
2251static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
2252{
2253 stlport_t *portp;
2254 int chipmask, i;
2255
2256#if DEBUG
2257 printk("stl_initports(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
2258#endif
2259
2260 chipmask = stl_panelinit(brdp, panelp);
2261
2262
2263
2264
2265
2266 for (i = 0; (i < panelp->nrports); i++) {
2267 portp = (stlport_t *) stl_memalloc(sizeof(stlport_t));
2268 if (portp == (stlport_t *) NULL) {
2269 printk("STALLION: failed to allocate memory "
2270 "(size=%d)\n", sizeof(stlport_t));
2271 break;
2272 }
2273 memset(portp, 0, sizeof(stlport_t));
2274
2275 portp->magic = STL_PORTMAGIC;
2276 portp->portnr = i;
2277 portp->brdnr = panelp->brdnr;
2278 portp->panelnr = panelp->panelnr;
2279 portp->uartp = panelp->uartp;
2280 portp->clk = brdp->clk;
2281 portp->baud_base = STL_BAUDBASE;
2282 portp->close_delay = STL_CLOSEDELAY;
2283 portp->closing_wait = 30 * HZ;
2284 portp->normaltermios = stl_deftermios;
2285 portp->callouttermios = stl_deftermios;
2286 portp->tqueue.routine = stl_offintr;
2287 portp->tqueue.data = portp;
2288 init_waitqueue_head(&portp->open_wait);
2289 init_waitqueue_head(&portp->close_wait);
2290 portp->stats.brd = portp->brdnr;
2291 portp->stats.panel = portp->panelnr;
2292 portp->stats.port = portp->portnr;
2293 panelp->ports[i] = portp;
2294 stl_portinit(brdp, panelp, portp);
2295 }
2296
2297 return(0);
2298}
2299
2300
2301
2302
2303
2304
2305
2306static inline int stl_initeio(stlbrd_t *brdp)
2307{
2308 stlpanel_t *panelp;
2309 unsigned int status;
2310 char *name;
2311
2312#if DEBUG
2313 printk("stl_initeio(brdp=%x)\n", (int) brdp);
2314#endif
2315
2316 brdp->ioctrl = brdp->ioaddr1 + 1;
2317 brdp->iostatus = brdp->ioaddr1 + 2;
2318
2319 status = inb(brdp->iostatus);
2320 if ((status & EIO_IDBITMASK) == EIO_MK3)
2321 brdp->ioctrl++;
2322
2323
2324
2325
2326
2327 if (brdp->brdtype == BRD_EASYIOPCI) {
2328 brdp->iosize1 = 0x80;
2329 brdp->iosize2 = 0x80;
2330 name = "serial(EIO-PCI)";
2331 outb(0x41, (brdp->ioaddr2 + 0x4c));
2332 } else {
2333 brdp->iosize1 = 8;
2334 name = "serial(EIO)";
2335 if ((brdp->irq < 0) || (brdp->irq > 15) ||
2336 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
2337 printk("STALLION: invalid irq=%d for brd=%d\n",
2338 brdp->irq, brdp->brdnr);
2339 return(-EINVAL);
2340 }
2341 outb((stl_vecmap[brdp->irq] | EIO_0WS |
2342 ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)),
2343 brdp->ioctrl);
2344 }
2345
2346 if (check_region(brdp->ioaddr1, brdp->iosize1)) {
2347 printk("STALLION: Warning, board %d I/O address %x conflicts "
2348 "with another device\n", brdp->brdnr, brdp->ioaddr1);
2349 }
2350 if (brdp->iosize2 > 0) {
2351 if (check_region(brdp->ioaddr2, brdp->iosize2)) {
2352 printk("STALLION: Warning, board %d I/O address %x "
2353 "conflicts with another device\n",
2354 brdp->brdnr, brdp->ioaddr2);
2355 }
2356 }
2357
2358
2359
2360
2361 brdp->clk = CD1400_CLK;
2362 brdp->isr = stl_eiointr;
2363
2364 switch (status & EIO_IDBITMASK) {
2365 case EIO_8PORTM:
2366 brdp->clk = CD1400_CLK8M;
2367
2368 case EIO_8PORTRS:
2369 case EIO_8PORTDI:
2370 brdp->nrports = 8;
2371 break;
2372 case EIO_4PORTRS:
2373 brdp->nrports = 4;
2374 break;
2375 case EIO_MK3:
2376 switch (status & EIO_BRDMASK) {
2377 case ID_BRD4:
2378 brdp->nrports = 4;
2379 break;
2380 case ID_BRD8:
2381 brdp->nrports = 8;
2382 break;
2383 case ID_BRD16:
2384 brdp->nrports = 16;
2385 break;
2386 default:
2387 return(-ENODEV);
2388 }
2389 break;
2390 default:
2391 return(-ENODEV);
2392 }
2393
2394
2395
2396
2397
2398 request_region(brdp->ioaddr1, brdp->iosize1, name);
2399 if (brdp->iosize2 > 0)
2400 request_region(brdp->ioaddr2, brdp->iosize2, name);
2401
2402 panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
2403 if (panelp == (stlpanel_t *) NULL) {
2404 printk("STALLION: failed to allocate memory (size=%d)\n",
2405 sizeof(stlpanel_t));
2406 return(-ENOMEM);
2407 }
2408 memset(panelp, 0, sizeof(stlpanel_t));
2409
2410 panelp->magic = STL_PANELMAGIC;
2411 panelp->brdnr = brdp->brdnr;
2412 panelp->panelnr = 0;
2413 panelp->nrports = brdp->nrports;
2414 panelp->iobase = brdp->ioaddr1;
2415 panelp->hwid = status;
2416 if ((status & EIO_IDBITMASK) == EIO_MK3) {
2417 panelp->uartp = (void *) &stl_sc26198uart;
2418 panelp->isr = stl_sc26198intr;
2419 } else {
2420 panelp->uartp = (void *) &stl_cd1400uart;
2421 panelp->isr = stl_cd1400eiointr;
2422 }
2423
2424 brdp->panels[0] = panelp;
2425 brdp->nrpanels = 1;
2426 brdp->state |= BRD_FOUND;
2427 brdp->hwid = status;
2428 if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
2429 printk("STALLION: failed to register interrupt "
2430 "routine for %s irq=%d\n", name, brdp->irq);
2431 return -ENODEV;
2432 }
2433
2434 return 0;
2435}
2436
2437
2438
2439
2440
2441
2442
2443
2444static int inline stl_initech(stlbrd_t *brdp)
2445{
2446 stlpanel_t *panelp;
2447 unsigned int status, nxtid, ioaddr, conflict;
2448 int panelnr, banknr, i;
2449 char *name;
2450
2451#if DEBUG
2452 printk("stl_initech(brdp=%x)\n", (int) brdp);
2453#endif
2454
2455 status = 0;
2456 conflict = 0;
2457
2458
2459
2460
2461
2462
2463 switch (brdp->brdtype) {
2464
2465 case BRD_ECH:
2466 brdp->isr = stl_echatintr;
2467 brdp->ioctrl = brdp->ioaddr1 + 1;
2468 brdp->iostatus = brdp->ioaddr1 + 1;
2469 status = inb(brdp->iostatus);
2470 if ((status & ECH_IDBITMASK) != ECH_ID)
2471 return(-ENODEV);
2472 if ((brdp->irq < 0) || (brdp->irq > 15) ||
2473 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
2474 printk("STALLION: invalid irq=%d for brd=%d\n",
2475 brdp->irq, brdp->brdnr);
2476 return(-EINVAL);
2477 }
2478 status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1);
2479 status |= (stl_vecmap[brdp->irq] << 1);
2480 outb((status | ECH_BRDRESET), brdp->ioaddr1);
2481 brdp->ioctrlval = ECH_INTENABLE |
2482 ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE);
2483 for (i = 0; (i < 10); i++)
2484 outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
2485 brdp->iosize1 = 2;
2486 brdp->iosize2 = 32;
2487 name = "serial(EC8/32)";
2488 outb(status, brdp->ioaddr1);
2489 break;
2490
2491 case BRD_ECHMC:
2492 brdp->isr = stl_echmcaintr;
2493 brdp->ioctrl = brdp->ioaddr1 + 0x20;
2494 brdp->iostatus = brdp->ioctrl;
2495 status = inb(brdp->iostatus);
2496 if ((status & ECH_IDBITMASK) != ECH_ID)
2497 return(-ENODEV);
2498 if ((brdp->irq < 0) || (brdp->irq > 15) ||
2499 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
2500 printk("STALLION: invalid irq=%d for brd=%d\n",
2501 brdp->irq, brdp->brdnr);
2502 return(-EINVAL);
2503 }
2504 outb(ECHMC_BRDRESET, brdp->ioctrl);
2505 outb(ECHMC_INTENABLE, brdp->ioctrl);
2506 brdp->iosize1 = 64;
2507 name = "serial(EC8/32-MC)";
2508 break;
2509
2510 case BRD_ECHPCI:
2511 brdp->isr = stl_echpciintr;
2512 brdp->ioctrl = brdp->ioaddr1 + 2;
2513 brdp->iosize1 = 4;
2514 brdp->iosize2 = 8;
2515 name = "serial(EC8/32-PCI)";
2516 break;
2517
2518 case BRD_ECH64PCI:
2519 brdp->isr = stl_echpci64intr;
2520 brdp->ioctrl = brdp->ioaddr2 + 0x40;
2521 outb(0x43, (brdp->ioaddr1 + 0x4c));
2522 brdp->iosize1 = 0x80;
2523 brdp->iosize2 = 0x80;
2524 name = "serial(EC8/64-PCI)";
2525 break;
2526
2527 default:
2528 printk("STALLION: unknown board type=%d\n", brdp->brdtype);
2529 return(-EINVAL);
2530 break;
2531 }
2532
2533
2534
2535
2536
2537 conflict = check_region(brdp->ioaddr1, brdp->iosize1) ?
2538 brdp->ioaddr1 : 0;
2539 if ((conflict == 0) && (brdp->iosize2 > 0))
2540 conflict = check_region(brdp->ioaddr2, brdp->iosize2) ?
2541 brdp->ioaddr2 : 0;
2542 if (conflict) {
2543 printk("STALLION: Warning, board %d I/O address %x conflicts "
2544 "with another device\n", brdp->brdnr, conflict);
2545 }
2546
2547 request_region(brdp->ioaddr1, brdp->iosize1, name);
2548 if (brdp->iosize2 > 0)
2549 request_region(brdp->ioaddr2, brdp->iosize2, name);
2550
2551
2552
2553
2554
2555 brdp->clk = CD1400_CLK;
2556 brdp->hwid = status;
2557
2558 ioaddr = brdp->ioaddr2;
2559 banknr = 0;
2560 panelnr = 0;
2561 nxtid = 0;
2562
2563 for (i = 0; (i < STL_MAXPANELS); i++) {
2564 if (brdp->brdtype == BRD_ECHPCI) {
2565 outb(nxtid, brdp->ioctrl);
2566 ioaddr = brdp->ioaddr2;
2567 }
2568 status = inb(ioaddr + ECH_PNLSTATUS);
2569 if ((status & ECH_PNLIDMASK) != nxtid)
2570 break;
2571 panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t));
2572 if (panelp == (stlpanel_t *) NULL) {
2573 printk("STALLION: failed to allocate memory "
2574 "(size=%d)\n", sizeof(stlpanel_t));
2575 break;
2576 }
2577 memset(panelp, 0, sizeof(stlpanel_t));
2578 panelp->magic = STL_PANELMAGIC;
2579 panelp->brdnr = brdp->brdnr;
2580 panelp->panelnr = panelnr;
2581 panelp->iobase = ioaddr;
2582 panelp->pagenr = nxtid;
2583 panelp->hwid = status;
2584 brdp->bnk2panel[banknr] = panelp;
2585 brdp->bnkpageaddr[banknr] = nxtid;
2586 brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS;
2587
2588 if (status & ECH_PNLXPID) {
2589 panelp->uartp = (void *) &stl_sc26198uart;
2590 panelp->isr = stl_sc26198intr;
2591 if (status & ECH_PNL16PORT) {
2592 panelp->nrports = 16;
2593 brdp->bnk2panel[banknr] = panelp;
2594 brdp->bnkpageaddr[banknr] = nxtid;
2595 brdp->bnkstataddr[banknr++] = ioaddr + 4 +
2596 ECH_PNLSTATUS;
2597 } else {
2598 panelp->nrports = 8;
2599 }
2600 } else {
2601 panelp->uartp = (void *) &stl_cd1400uart;
2602 panelp->isr = stl_cd1400echintr;
2603 if (status & ECH_PNL16PORT) {
2604 panelp->nrports = 16;
2605 panelp->ackmask = 0x80;
2606 if (brdp->brdtype != BRD_ECHPCI)
2607 ioaddr += EREG_BANKSIZE;
2608 brdp->bnk2panel[banknr] = panelp;
2609 brdp->bnkpageaddr[banknr] = ++nxtid;
2610 brdp->bnkstataddr[banknr++] = ioaddr +
2611 ECH_PNLSTATUS;
2612 } else {
2613 panelp->nrports = 8;
2614 panelp->ackmask = 0xc0;
2615 }
2616 }
2617
2618 nxtid++;
2619 ioaddr += EREG_BANKSIZE;
2620 brdp->nrports += panelp->nrports;
2621 brdp->panels[panelnr++] = panelp;
2622 if ((brdp->brdtype != BRD_ECHPCI) &&
2623 (ioaddr >= (brdp->ioaddr2 + brdp->iosize2)))
2624 break;
2625 }
2626
2627 brdp->nrpanels = panelnr;
2628 brdp->nrbnks = banknr;
2629 if (brdp->brdtype == BRD_ECH)
2630 outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
2631
2632 brdp->state |= BRD_FOUND;
2633 if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
2634 printk("STALLION: failed to register interrupt "
2635 "routine for %s irq=%d\n", name, brdp->irq);
2636 i = -ENODEV;
2637 }
2638
2639 return(i);
2640}
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651static int __init stl_brdinit(stlbrd_t *brdp)
2652{
2653 int i;
2654
2655#if DEBUG
2656 printk("stl_brdinit(brdp=%x)\n", (int) brdp);
2657#endif
2658
2659 switch (brdp->brdtype) {
2660 case BRD_EASYIO:
2661 case BRD_EASYIOPCI:
2662 stl_initeio(brdp);
2663 break;
2664 case BRD_ECH:
2665 case BRD_ECHMC:
2666 case BRD_ECHPCI:
2667 case BRD_ECH64PCI:
2668 stl_initech(brdp);
2669 break;
2670 default:
2671 printk("STALLION: board=%d is unknown board type=%d\n",
2672 brdp->brdnr, brdp->brdtype);
2673 return(ENODEV);
2674 }
2675
2676 stl_brds[brdp->brdnr] = brdp;
2677 if ((brdp->state & BRD_FOUND) == 0) {
2678 printk("STALLION: %s board not found, board=%d io=%x irq=%d\n",
2679 stl_brdnames[brdp->brdtype], brdp->brdnr,
2680 brdp->ioaddr1, brdp->irq);
2681 return(ENODEV);
2682 }
2683
2684 for (i = 0; (i < STL_MAXPANELS); i++)
2685 if (brdp->panels[i] != (stlpanel_t *) NULL)
2686 stl_initports(brdp, brdp->panels[i]);
2687
2688 printk("STALLION: %s found, board=%d io=%x irq=%d "
2689 "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype],
2690 brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels,
2691 brdp->nrports);
2692 return(0);
2693}
2694
2695
2696
2697
2698
2699
2700
2701static inline int stl_getbrdnr()
2702{
2703 int i;
2704
2705 for (i = 0; (i < STL_MAXBRDS); i++) {
2706 if (stl_brds[i] == (stlbrd_t *) NULL) {
2707 if (i >= stl_nrbrds)
2708 stl_nrbrds = i + 1;
2709 return(i);
2710 }
2711 }
2712 return(-1);
2713}
2714
2715
2716
2717#ifdef CONFIG_PCI
2718
2719
2720
2721
2722
2723
2724
2725static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
2726{
2727 stlbrd_t *brdp;
2728
2729#if DEBUG
2730 printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype,
2731 devp->bus->number, devp->devfn);
2732#endif
2733
2734 if (pci_enable_device(devp))
2735 return(-EIO);
2736 if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
2737 return(-ENOMEM);
2738 if ((brdp->brdnr = stl_getbrdnr()) < 0) {
2739 printk("STALLION: too many boards found, "
2740 "maximum supported %d\n", STL_MAXBRDS);
2741 return(0);
2742 }
2743 brdp->brdtype = brdtype;
2744
2745
2746
2747
2748
2749#if DEBUG
2750 printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__,
2751 pci_resource_start(devp, 0), pci_resource_start(devp, 1),
2752 pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq);
2753#endif
2754
2755
2756
2757
2758
2759 switch (brdtype) {
2760 case BRD_ECHPCI:
2761 brdp->ioaddr2 = pci_resource_start(devp, 0);
2762 brdp->ioaddr1 = pci_resource_start(devp, 1);
2763 break;
2764 case BRD_ECH64PCI:
2765 brdp->ioaddr2 = pci_resource_start(devp, 2);
2766 brdp->ioaddr1 = pci_resource_start(devp, 1);
2767 break;
2768 case BRD_EASYIOPCI:
2769 brdp->ioaddr1 = pci_resource_start(devp, 2);
2770 brdp->ioaddr2 = pci_resource_start(devp, 1);
2771 break;
2772 default:
2773 printk("STALLION: unknown PCI board type=%d\n", brdtype);
2774 break;
2775 }
2776
2777 brdp->irq = devp->irq;
2778 stl_brdinit(brdp);
2779
2780 return(0);
2781}
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791static inline int stl_findpcibrds()
2792{
2793 struct pci_dev *dev = NULL;
2794 int i, rc;
2795
2796#if DEBUG
2797 printk("stl_findpcibrds()\n");
2798#endif
2799
2800 if (! pci_present())
2801 return(0);
2802
2803 for (i = 0; (i < stl_nrpcibrds); i++)
2804 while ((dev = pci_find_device(stl_pcibrds[i].vendid,
2805 stl_pcibrds[i].devid, dev))) {
2806
2807
2808
2809
2810
2811 if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
2812 continue;
2813
2814 rc = stl_initpcibrd(stl_pcibrds[i].brdtype, dev);
2815 if (rc)
2816 return(rc);
2817 }
2818
2819 return(0);
2820}
2821
2822#endif
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832static inline int stl_initbrds()
2833{
2834 stlbrd_t *brdp;
2835 stlconf_t *confp;
2836 int i;
2837
2838#if DEBUG
2839 printk("stl_initbrds()\n");
2840#endif
2841
2842 if (stl_nrbrds > STL_MAXBRDS) {
2843 printk("STALLION: too many boards in configuration table, "
2844 "truncating to %d\n", STL_MAXBRDS);
2845 stl_nrbrds = STL_MAXBRDS;
2846 }
2847
2848
2849
2850
2851
2852 for (i = 0; (i < stl_nrbrds); i++) {
2853 confp = &stl_brdconf[i];
2854#ifdef MODULE
2855 stl_parsebrd(confp, stl_brdsp[i]);
2856#endif
2857 if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
2858 return(-ENOMEM);
2859 brdp->brdnr = i;
2860 brdp->brdtype = confp->brdtype;
2861 brdp->ioaddr1 = confp->ioaddr1;
2862 brdp->ioaddr2 = confp->ioaddr2;
2863 brdp->irq = confp->irq;
2864 brdp->irqtype = confp->irqtype;
2865 stl_brdinit(brdp);
2866 }
2867
2868
2869
2870
2871
2872#ifdef MODULE
2873 stl_argbrds();
2874#endif
2875#ifdef CONFIG_PCI
2876 stl_findpcibrds();
2877#endif
2878
2879 return(0);
2880}
2881
2882
2883
2884
2885
2886
2887
2888static int stl_getbrdstats(combrd_t *bp)
2889{
2890 stlbrd_t *brdp;
2891 stlpanel_t *panelp;
2892 int i;
2893
2894 if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t)))
2895 return -EFAULT;
2896 if (stl_brdstats.brd >= STL_MAXBRDS)
2897 return(-ENODEV);
2898 brdp = stl_brds[stl_brdstats.brd];
2899 if (brdp == (stlbrd_t *) NULL)
2900 return(-ENODEV);
2901
2902 memset(&stl_brdstats, 0, sizeof(combrd_t));
2903 stl_brdstats.brd = brdp->brdnr;
2904 stl_brdstats.type = brdp->brdtype;
2905 stl_brdstats.hwid = brdp->hwid;
2906 stl_brdstats.state = brdp->state;
2907 stl_brdstats.ioaddr = brdp->ioaddr1;
2908 stl_brdstats.ioaddr2 = brdp->ioaddr2;
2909 stl_brdstats.irq = brdp->irq;
2910 stl_brdstats.nrpanels = brdp->nrpanels;
2911 stl_brdstats.nrports = brdp->nrports;
2912 for (i = 0; (i < brdp->nrpanels); i++) {
2913 panelp = brdp->panels[i];
2914 stl_brdstats.panels[i].panel = i;
2915 stl_brdstats.panels[i].hwid = panelp->hwid;
2916 stl_brdstats.panels[i].nrports = panelp->nrports;
2917 }
2918
2919 return copy_to_user(bp, &stl_brdstats, sizeof(combrd_t)) ? -EFAULT : 0;
2920}
2921
2922
2923
2924
2925
2926
2927
2928static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
2929{
2930 stlbrd_t *brdp;
2931 stlpanel_t *panelp;
2932
2933 if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
2934 return((stlport_t *) NULL);
2935 brdp = stl_brds[brdnr];
2936 if (brdp == (stlbrd_t *) NULL)
2937 return((stlport_t *) NULL);
2938 if ((panelnr < 0) || (panelnr >= brdp->nrpanels))
2939 return((stlport_t *) NULL);
2940 panelp = brdp->panels[panelnr];
2941 if (panelp == (stlpanel_t *) NULL)
2942 return((stlport_t *) NULL);
2943 if ((portnr < 0) || (portnr >= panelp->nrports))
2944 return((stlport_t *) NULL);
2945 return(panelp->ports[portnr]);
2946}
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956static int stl_getportstats(stlport_t *portp, comstats_t *cp)
2957{
2958 unsigned char *head, *tail;
2959 unsigned long flags;
2960
2961 if (portp == (stlport_t *) NULL) {
2962 if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
2963 return -EFAULT;
2964 portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
2965 stl_comstats.port);
2966 if (portp == (stlport_t *) NULL)
2967 return(-ENODEV);
2968 }
2969
2970 portp->stats.state = portp->istate;
2971 portp->stats.flags = portp->flags;
2972 portp->stats.hwid = portp->hwid;
2973
2974 portp->stats.ttystate = 0;
2975 portp->stats.cflags = 0;
2976 portp->stats.iflags = 0;
2977 portp->stats.oflags = 0;
2978 portp->stats.lflags = 0;
2979 portp->stats.rxbuffered = 0;
2980
2981 save_flags(flags);
2982 cli();
2983 if (portp->tty != (struct tty_struct *) NULL) {
2984 if (portp->tty->driver_data == portp) {
2985 portp->stats.ttystate = portp->tty->flags;
2986 portp->stats.rxbuffered = portp->tty->flip.count;
2987 if (portp->tty->termios != (struct termios *) NULL) {
2988 portp->stats.cflags = portp->tty->termios->c_cflag;
2989 portp->stats.iflags = portp->tty->termios->c_iflag;
2990 portp->stats.oflags = portp->tty->termios->c_oflag;
2991 portp->stats.lflags = portp->tty->termios->c_lflag;
2992 }
2993 }
2994 }
2995 restore_flags(flags);
2996
2997 head = portp->tx.head;
2998 tail = portp->tx.tail;
2999 portp->stats.txbuffered = ((head >= tail) ? (head - tail) :
3000 (STL_TXBUFSIZE - (tail - head)));
3001
3002 portp->stats.signals = (unsigned long) stl_getsignals(portp);
3003
3004 return copy_to_user(cp, &portp->stats,
3005 sizeof(comstats_t)) ? -EFAULT : 0;
3006}
3007
3008
3009
3010
3011
3012
3013
3014static int stl_clrportstats(stlport_t *portp, comstats_t *cp)
3015{
3016 if (portp == (stlport_t *) NULL) {
3017 if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
3018 return -EFAULT;
3019 portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
3020 stl_comstats.port);
3021 if (portp == (stlport_t *) NULL)
3022 return(-ENODEV);
3023 }
3024
3025 memset(&portp->stats, 0, sizeof(comstats_t));
3026 portp->stats.brd = portp->brdnr;
3027 portp->stats.panel = portp->panelnr;
3028 portp->stats.port = portp->portnr;
3029 return copy_to_user(cp, &portp->stats,
3030 sizeof(comstats_t)) ? -EFAULT : 0;
3031}
3032
3033
3034
3035
3036
3037
3038
3039static int stl_getportstruct(unsigned long arg)
3040{
3041 stlport_t *portp;
3042
3043 if (copy_from_user(&stl_dummyport, (void *) arg, sizeof(stlport_t)))
3044 return -EFAULT;
3045 portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
3046 stl_dummyport.portnr);
3047 if (portp == (stlport_t *) NULL)
3048 return(-ENODEV);
3049 return copy_to_user((void *)arg, portp,
3050 sizeof(stlport_t)) ? -EFAULT : 0;
3051}
3052
3053
3054
3055
3056
3057
3058
3059static int stl_getbrdstruct(unsigned long arg)
3060{
3061 stlbrd_t *brdp;
3062
3063 if (copy_from_user(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t)))
3064 return -EFAULT;
3065 if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
3066 return(-ENODEV);
3067 brdp = stl_brds[stl_dummybrd.brdnr];
3068 if (brdp == (stlbrd_t *) NULL)
3069 return(-ENODEV);
3070 return copy_to_user((void *)arg, brdp, sizeof(stlbrd_t)) ? -EFAULT : 0;
3071}
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
3082{
3083 int brdnr, rc;
3084
3085#if DEBUG
3086 printk("stl_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip,
3087 (int) fp, cmd, (int) arg);
3088#endif
3089
3090 brdnr = MINOR(ip->i_rdev);
3091 if (brdnr >= STL_MAXBRDS)
3092 return(-ENODEV);
3093 rc = 0;
3094
3095 switch (cmd) {
3096 case COM_GETPORTSTATS:
3097 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
3098 sizeof(comstats_t))) == 0)
3099 rc = stl_getportstats((stlport_t *) NULL,
3100 (comstats_t *) arg);
3101 break;
3102 case COM_CLRPORTSTATS:
3103 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
3104 sizeof(comstats_t))) == 0)
3105 rc = stl_clrportstats((stlport_t *) NULL,
3106 (comstats_t *) arg);
3107 break;
3108 case COM_GETBRDSTATS:
3109 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
3110 sizeof(combrd_t))) == 0)
3111 rc = stl_getbrdstats((combrd_t *) arg);
3112 break;
3113 case COM_READPORT:
3114 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
3115 sizeof(stlport_t))) == 0)
3116 rc = stl_getportstruct(arg);
3117 break;
3118 case COM_READBOARD:
3119 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
3120 sizeof(stlbrd_t))) == 0)
3121 rc = stl_getbrdstruct(arg);
3122 break;
3123 default:
3124 rc = -ENOIOCTLCMD;
3125 break;
3126 }
3127
3128 return(rc);
3129}
3130
3131
3132
3133int __init stl_init(void)
3134{
3135 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
3136
3137 stl_initbrds();
3138
3139
3140
3141
3142 stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE);
3143 if (stl_tmpwritebuf == (char *) NULL)
3144 printk("STALLION: failed to allocate memory (size=%d)\n",
3145 STL_TXBUFSIZE);
3146
3147
3148
3149
3150
3151 if (devfs_register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
3152 printk("STALLION: failed to register serial board device\n");
3153 devfs_handle = devfs_mk_dir (NULL, "staliomem", NULL);
3154 devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
3155 STL_SIOMEMMAJOR, 0,
3156 S_IFCHR | S_IRUSR | S_IWUSR,
3157 &stl_fsiomem, NULL);
3158
3159
3160
3161
3162
3163 memset(&stl_serial, 0, sizeof(struct tty_driver));
3164 stl_serial.magic = TTY_DRIVER_MAGIC;
3165 stl_serial.driver_name = stl_drvname;
3166 stl_serial.name = stl_serialname;
3167 stl_serial.major = STL_SERIALMAJOR;
3168 stl_serial.minor_start = 0;
3169 stl_serial.num = STL_MAXBRDS * STL_MAXPORTS;
3170 stl_serial.type = TTY_DRIVER_TYPE_SERIAL;
3171 stl_serial.subtype = STL_DRVTYPSERIAL;
3172 stl_serial.init_termios = stl_deftermios;
3173 stl_serial.flags = TTY_DRIVER_REAL_RAW;
3174 stl_serial.refcount = &stl_refcount;
3175 stl_serial.table = stl_ttys;
3176 stl_serial.termios = stl_termios;
3177 stl_serial.termios_locked = stl_termioslocked;
3178
3179 stl_serial.open = stl_open;
3180 stl_serial.close = stl_close;
3181 stl_serial.write = stl_write;
3182 stl_serial.put_char = stl_putchar;
3183 stl_serial.flush_chars = stl_flushchars;
3184 stl_serial.write_room = stl_writeroom;
3185 stl_serial.chars_in_buffer = stl_charsinbuffer;
3186 stl_serial.ioctl = stl_ioctl;
3187 stl_serial.set_termios = stl_settermios;
3188 stl_serial.throttle = stl_throttle;
3189 stl_serial.unthrottle = stl_unthrottle;
3190 stl_serial.stop = stl_stop;
3191 stl_serial.start = stl_start;
3192 stl_serial.hangup = stl_hangup;
3193 stl_serial.flush_buffer = stl_flushbuffer;
3194 stl_serial.break_ctl = stl_breakctl;
3195 stl_serial.wait_until_sent = stl_waituntilsent;
3196 stl_serial.send_xchar = stl_sendxchar;
3197 stl_serial.read_proc = stl_readproc;
3198
3199 stl_callout = stl_serial;
3200 stl_callout.name = stl_calloutname;
3201 stl_callout.major = STL_CALLOUTMAJOR;
3202 stl_callout.subtype = STL_DRVTYPCALLOUT;
3203 stl_callout.read_proc = 0;
3204
3205 if (tty_register_driver(&stl_serial))
3206 printk("STALLION: failed to register serial driver\n");
3207 if (tty_register_driver(&stl_callout))
3208 printk("STALLION: failed to register callout driver\n");
3209
3210 return(0);
3211}
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223static int stl_cd1400getreg(stlport_t *portp, int regnr)
3224{
3225 outb((regnr + portp->uartaddr), portp->ioaddr);
3226 return(inb(portp->ioaddr + EREG_DATA));
3227}
3228
3229static void stl_cd1400setreg(stlport_t *portp, int regnr, int value)
3230{
3231 outb((regnr + portp->uartaddr), portp->ioaddr);
3232 outb(value, portp->ioaddr + EREG_DATA);
3233}
3234
3235static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value)
3236{
3237 outb((regnr + portp->uartaddr), portp->ioaddr);
3238 if (inb(portp->ioaddr + EREG_DATA) != value) {
3239 outb(value, portp->ioaddr + EREG_DATA);
3240 return(1);
3241 }
3242 return(0);
3243}
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
3254{
3255 unsigned int gfrcr;
3256 int chipmask, i, j;
3257 int nrchips, uartaddr, ioaddr;
3258
3259#if DEBUG
3260 printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
3261#endif
3262
3263 BRDENABLE(panelp->brdnr, panelp->pagenr);
3264
3265
3266
3267
3268 chipmask = 0;
3269 nrchips = panelp->nrports / CD1400_PORTS;
3270 for (i = 0; (i < nrchips); i++) {
3271 if (brdp->brdtype == BRD_ECHPCI) {
3272 outb((panelp->pagenr + (i >> 1)), brdp->ioctrl);
3273 ioaddr = panelp->iobase;
3274 } else {
3275 ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1));
3276 }
3277 uartaddr = (i & 0x01) ? 0x080 : 0;
3278 outb((GFRCR + uartaddr), ioaddr);
3279 outb(0, (ioaddr + EREG_DATA));
3280 outb((CCR + uartaddr), ioaddr);
3281 outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
3282 outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
3283 outb((GFRCR + uartaddr), ioaddr);
3284 for (j = 0; (j < CCR_MAXWAIT); j++) {
3285 if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0)
3286 break;
3287 }
3288 if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) {
3289 printk("STALLION: cd1400 not responding, "
3290 "brd=%d panel=%d chip=%d\n",
3291 panelp->brdnr, panelp->panelnr, i);
3292 continue;
3293 }
3294 chipmask |= (0x1 << i);
3295 outb((PPR + uartaddr), ioaddr);
3296 outb(PPR_SCALAR, (ioaddr + EREG_DATA));
3297 }
3298
3299 BRDDISABLE(panelp->brdnr);
3300 return(chipmask);
3301}
3302
3303
3304
3305
3306
3307
3308
3309static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
3310{
3311#if DEBUG
3312 printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n",
3313 (int) brdp, (int) panelp, (int) portp);
3314#endif
3315
3316 if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
3317 (portp == (stlport_t *) NULL))
3318 return;
3319
3320 portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) ||
3321 (portp->portnr < 8)) ? 0 : EREG_BANKSIZE);
3322 portp->uartaddr = (portp->portnr & 0x04) << 5;
3323 portp->pagenr = panelp->pagenr + (portp->portnr >> 3);
3324
3325 BRDENABLE(portp->brdnr, portp->pagenr);
3326 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3327 stl_cd1400setreg(portp, LIVR, (portp->portnr << 3));
3328 portp->hwid = stl_cd1400getreg(portp, GFRCR);
3329 BRDDISABLE(portp->brdnr);
3330}
3331
3332
3333
3334
3335
3336
3337
3338
3339static void stl_cd1400ccrwait(stlport_t *portp)
3340{
3341 int i;
3342
3343 for (i = 0; (i < CCR_MAXWAIT); i++) {
3344 if (stl_cd1400getreg(portp, CCR) == 0) {
3345 return;
3346 }
3347 }
3348
3349 printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n",
3350 portp->portnr, portp->panelnr, portp->brdnr);
3351}
3352
3353
3354
3355
3356
3357
3358
3359
3360static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
3361{
3362 stlbrd_t *brdp;
3363 unsigned long flags;
3364 unsigned int clkdiv, baudrate;
3365 unsigned char cor1, cor2, cor3;
3366 unsigned char cor4, cor5, ccr;
3367 unsigned char srer, sreron, sreroff;
3368 unsigned char mcor1, mcor2, rtpr;
3369 unsigned char clk, div;
3370
3371 cor1 = 0;
3372 cor2 = 0;
3373 cor3 = 0;
3374 cor4 = 0;
3375 cor5 = 0;
3376 ccr = 0;
3377 rtpr = 0;
3378 clk = 0;
3379 div = 0;
3380 mcor1 = 0;
3381 mcor2 = 0;
3382 sreron = 0;
3383 sreroff = 0;
3384
3385 brdp = stl_brds[portp->brdnr];
3386 if (brdp == (stlbrd_t *) NULL)
3387 return;
3388
3389
3390
3391
3392
3393
3394 portp->rxignoremsk = 0;
3395 if (tiosp->c_iflag & IGNPAR) {
3396 portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN);
3397 cor1 |= COR1_PARIGNORE;
3398 }
3399 if (tiosp->c_iflag & IGNBRK) {
3400 portp->rxignoremsk |= ST_BREAK;
3401 cor4 |= COR4_IGNBRK;
3402 }
3403
3404 portp->rxmarkmsk = ST_OVERRUN;
3405 if (tiosp->c_iflag & (INPCK | PARMRK))
3406 portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING);
3407 if (tiosp->c_iflag & BRKINT)
3408 portp->rxmarkmsk |= ST_BREAK;
3409
3410
3411
3412
3413
3414 switch (tiosp->c_cflag & CSIZE) {
3415 case CS5:
3416 cor1 |= COR1_CHL5;
3417 break;
3418 case CS6:
3419 cor1 |= COR1_CHL6;
3420 break;
3421 case CS7:
3422 cor1 |= COR1_CHL7;
3423 break;
3424 default:
3425 cor1 |= COR1_CHL8;
3426 break;
3427 }
3428
3429 if (tiosp->c_cflag & CSTOPB)
3430 cor1 |= COR1_STOP2;
3431 else
3432 cor1 |= COR1_STOP1;
3433
3434 if (tiosp->c_cflag & PARENB) {
3435 if (tiosp->c_cflag & PARODD)
3436 cor1 |= (COR1_PARENB | COR1_PARODD);
3437 else
3438 cor1 |= (COR1_PARENB | COR1_PAREVEN);
3439 } else {
3440 cor1 |= COR1_PARNONE;
3441 }
3442
3443
3444
3445
3446
3447
3448
3449 cor3 |= FIFO_RXTHRESHOLD;
3450 rtpr = 2;
3451
3452
3453
3454
3455
3456
3457
3458 baudrate = tiosp->c_cflag & CBAUD;
3459 if (baudrate & CBAUDEX) {
3460 baudrate &= ~CBAUDEX;
3461 if ((baudrate < 1) || (baudrate > 4))
3462 tiosp->c_cflag &= ~CBAUDEX;
3463 else
3464 baudrate += 15;
3465 }
3466 baudrate = stl_baudrates[baudrate];
3467 if ((tiosp->c_cflag & CBAUD) == B38400) {
3468 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
3469 baudrate = 57600;
3470 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
3471 baudrate = 115200;
3472 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
3473 baudrate = 230400;
3474 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
3475 baudrate = 460800;
3476 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
3477 baudrate = (portp->baud_base / portp->custom_divisor);
3478 }
3479 if (baudrate > STL_CD1400MAXBAUD)
3480 baudrate = STL_CD1400MAXBAUD;
3481
3482 if (baudrate > 0) {
3483 for (clk = 0; (clk < CD1400_NUMCLKS); clk++) {
3484 clkdiv = ((portp->clk / stl_cd1400clkdivs[clk]) / baudrate);
3485 if (clkdiv < 0x100)
3486 break;
3487 }
3488 div = (unsigned char) clkdiv;
3489 }
3490
3491
3492
3493
3494 if ((tiosp->c_cflag & CLOCAL) == 0) {
3495 mcor1 |= MCOR1_DCD;
3496 mcor2 |= MCOR2_DCD;
3497 sreron |= SRER_MODEM;
3498 portp->flags |= ASYNC_CHECK_CD;
3499 } else {
3500 portp->flags &= ~ASYNC_CHECK_CD;
3501 }
3502
3503
3504
3505
3506
3507
3508
3509 if (tiosp->c_iflag & IXON) {
3510 cor2 |= COR2_TXIBE;
3511 cor3 |= COR3_SCD12;
3512 if (tiosp->c_iflag & IXANY)
3513 cor2 |= COR2_IXM;
3514 }
3515
3516 if (tiosp->c_cflag & CRTSCTS) {
3517 cor2 |= COR2_CTSAE;
3518 mcor1 |= FIFO_RTSTHRESHOLD;
3519 }
3520
3521
3522
3523
3524
3525
3526#if DEBUG
3527 printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
3528 portp->portnr, portp->panelnr, portp->brdnr);
3529 printk(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n",
3530 cor1, cor2, cor3, cor4, cor5);
3531 printk(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n",
3532 mcor1, mcor2, rtpr, sreron, sreroff);
3533 printk(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
3534 printk(" schr1=%x schr2=%x schr3=%x schr4=%x\n",
3535 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
3536 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
3537#endif
3538
3539 save_flags(flags);
3540 cli();
3541 BRDENABLE(portp->brdnr, portp->pagenr);
3542 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3));
3543 srer = stl_cd1400getreg(portp, SRER);
3544 stl_cd1400setreg(portp, SRER, 0);
3545 if (stl_cd1400updatereg(portp, COR1, cor1))
3546 ccr = 1;
3547 if (stl_cd1400updatereg(portp, COR2, cor2))
3548 ccr = 1;
3549 if (stl_cd1400updatereg(portp, COR3, cor3))
3550 ccr = 1;
3551 if (ccr) {
3552 stl_cd1400ccrwait(portp);
3553 stl_cd1400setreg(portp, CCR, CCR_CORCHANGE);
3554 }
3555 stl_cd1400setreg(portp, COR4, cor4);
3556 stl_cd1400setreg(portp, COR5, cor5);
3557 stl_cd1400setreg(portp, MCOR1, mcor1);
3558 stl_cd1400setreg(portp, MCOR2, mcor2);
3559 if (baudrate > 0) {
3560 stl_cd1400setreg(portp, TCOR, clk);
3561 stl_cd1400setreg(portp, TBPR, div);
3562 stl_cd1400setreg(portp, RCOR, clk);
3563 stl_cd1400setreg(portp, RBPR, div);
3564 }
3565 stl_cd1400setreg(portp, SCHR1, tiosp->c_cc[VSTART]);
3566 stl_cd1400setreg(portp, SCHR2, tiosp->c_cc[VSTOP]);
3567 stl_cd1400setreg(portp, SCHR3, tiosp->c_cc[VSTART]);
3568 stl_cd1400setreg(portp, SCHR4, tiosp->c_cc[VSTOP]);
3569 stl_cd1400setreg(portp, RTPR, rtpr);
3570 mcor1 = stl_cd1400getreg(portp, MSVR1);
3571 if (mcor1 & MSVR1_DCD)
3572 portp->sigs |= TIOCM_CD;
3573 else
3574 portp->sigs &= ~TIOCM_CD;
3575 stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron));
3576 BRDDISABLE(portp->brdnr);
3577 restore_flags(flags);
3578}
3579
3580
3581
3582
3583
3584
3585
3586static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts)
3587{
3588 unsigned char msvr1, msvr2;
3589 unsigned long flags;
3590
3591#if DEBUG
3592 printk("stl_cd1400setsignals(portp=%x,dtr=%d,rts=%d)\n",
3593 (int) portp, dtr, rts);
3594#endif
3595
3596 msvr1 = 0;
3597 msvr2 = 0;
3598 if (dtr > 0)
3599 msvr1 = MSVR1_DTR;
3600 if (rts > 0)
3601 msvr2 = MSVR2_RTS;
3602
3603 save_flags(flags);
3604 cli();
3605 BRDENABLE(portp->brdnr, portp->pagenr);
3606 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3607 if (rts >= 0)
3608 stl_cd1400setreg(portp, MSVR2, msvr2);
3609 if (dtr >= 0)
3610 stl_cd1400setreg(portp, MSVR1, msvr1);
3611 BRDDISABLE(portp->brdnr);
3612 restore_flags(flags);
3613}
3614
3615
3616
3617
3618
3619
3620
3621static int stl_cd1400getsignals(stlport_t *portp)
3622{
3623 unsigned char msvr1, msvr2;
3624 unsigned long flags;
3625 int sigs;
3626
3627#if DEBUG
3628 printk("stl_cd1400getsignals(portp=%x)\n", (int) portp);
3629#endif
3630
3631 save_flags(flags);
3632 cli();
3633 BRDENABLE(portp->brdnr, portp->pagenr);
3634 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3635 msvr1 = stl_cd1400getreg(portp, MSVR1);
3636 msvr2 = stl_cd1400getreg(portp, MSVR2);
3637 BRDDISABLE(portp->brdnr);
3638 restore_flags(flags);
3639
3640 sigs = 0;
3641 sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0;
3642 sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0;
3643 sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0;
3644 sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0;
3645#if 0
3646 sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0;
3647 sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0;
3648#else
3649 sigs |= TIOCM_DSR;
3650#endif
3651 return(sigs);
3652}
3653
3654
3655
3656
3657
3658
3659
3660static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx)
3661{
3662 unsigned char ccr;
3663 unsigned long flags;
3664
3665#if DEBUG
3666 printk("stl_cd1400enablerxtx(portp=%x,rx=%d,tx=%d)\n",
3667 (int) portp, rx, tx);
3668#endif
3669 ccr = 0;
3670
3671 if (tx == 0)
3672 ccr |= CCR_TXDISABLE;
3673 else if (tx > 0)
3674 ccr |= CCR_TXENABLE;
3675 if (rx == 0)
3676 ccr |= CCR_RXDISABLE;
3677 else if (rx > 0)
3678 ccr |= CCR_RXENABLE;
3679
3680 save_flags(flags);
3681 cli();
3682 BRDENABLE(portp->brdnr, portp->pagenr);
3683 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3684 stl_cd1400ccrwait(portp);
3685 stl_cd1400setreg(portp, CCR, ccr);
3686 stl_cd1400ccrwait(portp);
3687 BRDDISABLE(portp->brdnr);
3688 restore_flags(flags);
3689}
3690
3691
3692
3693
3694
3695
3696
3697static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx)
3698{
3699 unsigned char sreron, sreroff;
3700 unsigned long flags;
3701
3702#if DEBUG
3703 printk("stl_cd1400startrxtx(portp=%x,rx=%d,tx=%d)\n",
3704 (int) portp, rx, tx);
3705#endif
3706
3707 sreron = 0;
3708 sreroff = 0;
3709 if (tx == 0)
3710 sreroff |= (SRER_TXDATA | SRER_TXEMPTY);
3711 else if (tx == 1)
3712 sreron |= SRER_TXDATA;
3713 else if (tx >= 2)
3714 sreron |= SRER_TXEMPTY;
3715 if (rx == 0)
3716 sreroff |= SRER_RXDATA;
3717 else if (rx > 0)
3718 sreron |= SRER_RXDATA;
3719
3720 save_flags(flags);
3721 cli();
3722 BRDENABLE(portp->brdnr, portp->pagenr);
3723 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3724 stl_cd1400setreg(portp, SRER,
3725 ((stl_cd1400getreg(portp, SRER) & ~sreroff) | sreron));
3726 BRDDISABLE(portp->brdnr);
3727 if (tx > 0)
3728 set_bit(ASYI_TXBUSY, &portp->istate);
3729 restore_flags(flags);
3730}
3731
3732
3733
3734
3735
3736
3737
3738static void stl_cd1400disableintrs(stlport_t *portp)
3739{
3740 unsigned long flags;
3741
3742#if DEBUG
3743 printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp);
3744#endif
3745 save_flags(flags);
3746 cli();
3747 BRDENABLE(portp->brdnr, portp->pagenr);
3748 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3749 stl_cd1400setreg(portp, SRER, 0);
3750 BRDDISABLE(portp->brdnr);
3751 restore_flags(flags);
3752}
3753
3754
3755
3756static void stl_cd1400sendbreak(stlport_t *portp, int len)
3757{
3758 unsigned long flags;
3759
3760#if DEBUG
3761 printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len);
3762#endif
3763
3764 save_flags(flags);
3765 cli();
3766 BRDENABLE(portp->brdnr, portp->pagenr);
3767 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3768 stl_cd1400setreg(portp, SRER,
3769 ((stl_cd1400getreg(portp, SRER) & ~SRER_TXDATA) |
3770 SRER_TXEMPTY));
3771 BRDDISABLE(portp->brdnr);
3772 portp->brklen = len;
3773 if (len == 1)
3774 portp->stats.txbreaks++;
3775 restore_flags(flags);
3776}
3777
3778
3779
3780
3781
3782
3783
3784static void stl_cd1400flowctrl(stlport_t *portp, int state)
3785{
3786 struct tty_struct *tty;
3787 unsigned long flags;
3788
3789#if DEBUG
3790 printk("stl_cd1400flowctrl(portp=%x,state=%x)\n", (int) portp, state);
3791#endif
3792
3793 if (portp == (stlport_t *) NULL)
3794 return;
3795 tty = portp->tty;
3796 if (tty == (struct tty_struct *) NULL)
3797 return;
3798
3799 save_flags(flags);
3800 cli();
3801 BRDENABLE(portp->brdnr, portp->pagenr);
3802 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3803
3804 if (state) {
3805 if (tty->termios->c_iflag & IXOFF) {
3806 stl_cd1400ccrwait(portp);
3807 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
3808 portp->stats.rxxon++;
3809 stl_cd1400ccrwait(portp);
3810 }
3811
3812
3813
3814
3815
3816
3817 if (tty->termios->c_cflag & CRTSCTS) {
3818 stl_cd1400setreg(portp, MCOR1,
3819 (stl_cd1400getreg(portp, MCOR1) |
3820 FIFO_RTSTHRESHOLD));
3821 stl_cd1400setreg(portp, MSVR2, MSVR2_RTS);
3822 portp->stats.rxrtson++;
3823 }
3824 } else {
3825 if (tty->termios->c_iflag & IXOFF) {
3826 stl_cd1400ccrwait(portp);
3827 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
3828 portp->stats.rxxoff++;
3829 stl_cd1400ccrwait(portp);
3830 }
3831 if (tty->termios->c_cflag & CRTSCTS) {
3832 stl_cd1400setreg(portp, MCOR1,
3833 (stl_cd1400getreg(portp, MCOR1) & 0xf0));
3834 stl_cd1400setreg(portp, MSVR2, 0);
3835 portp->stats.rxrtsoff++;
3836 }
3837 }
3838
3839 BRDDISABLE(portp->brdnr);
3840 restore_flags(flags);
3841}
3842
3843
3844
3845
3846
3847
3848
3849static void stl_cd1400sendflow(stlport_t *portp, int state)
3850{
3851 struct tty_struct *tty;
3852 unsigned long flags;
3853
3854#if DEBUG
3855 printk("stl_cd1400sendflow(portp=%x,state=%x)\n", (int) portp, state);
3856#endif
3857
3858 if (portp == (stlport_t *) NULL)
3859 return;
3860 tty = portp->tty;
3861 if (tty == (struct tty_struct *) NULL)
3862 return;
3863
3864 save_flags(flags);
3865 cli();
3866 BRDENABLE(portp->brdnr, portp->pagenr);
3867 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3868 if (state) {
3869 stl_cd1400ccrwait(portp);
3870 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
3871 portp->stats.rxxon++;
3872 stl_cd1400ccrwait(portp);
3873 } else {
3874 stl_cd1400ccrwait(portp);
3875 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
3876 portp->stats.rxxoff++;
3877 stl_cd1400ccrwait(portp);
3878 }
3879 BRDDISABLE(portp->brdnr);
3880 restore_flags(flags);
3881}
3882
3883
3884
3885static void stl_cd1400flush(stlport_t *portp)
3886{
3887 unsigned long flags;
3888
3889#if DEBUG
3890 printk("stl_cd1400flush(portp=%x)\n", (int) portp);
3891#endif
3892
3893 if (portp == (stlport_t *) NULL)
3894 return;
3895
3896 save_flags(flags);
3897 cli();
3898 BRDENABLE(portp->brdnr, portp->pagenr);
3899 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3900 stl_cd1400ccrwait(portp);
3901 stl_cd1400setreg(portp, CCR, CCR_TXFLUSHFIFO);
3902 stl_cd1400ccrwait(portp);
3903 portp->tx.tail = portp->tx.head;
3904 BRDDISABLE(portp->brdnr);
3905 restore_flags(flags);
3906}
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917static int stl_cd1400datastate(stlport_t *portp)
3918{
3919#if DEBUG
3920 printk("stl_cd1400datastate(portp=%x)\n", (int) portp);
3921#endif
3922
3923 if (portp == (stlport_t *) NULL)
3924 return(0);
3925
3926 return(test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0);
3927}
3928
3929
3930
3931
3932
3933
3934
3935static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase)
3936{
3937 unsigned char svrtype;
3938
3939#if DEBUG
3940 printk("stl_cd1400eiointr(panelp=%x,iobase=%x)\n",
3941 (int) panelp, iobase);
3942#endif
3943
3944 outb(SVRR, iobase);
3945 svrtype = inb(iobase + EREG_DATA);
3946 if (panelp->nrports > 4) {
3947 outb((SVRR + 0x80), iobase);
3948 svrtype |= inb(iobase + EREG_DATA);
3949 }
3950
3951 if (svrtype & SVRR_RX)
3952 stl_cd1400rxisr(panelp, iobase);
3953 else if (svrtype & SVRR_TX)
3954 stl_cd1400txisr(panelp, iobase);
3955 else if (svrtype & SVRR_MDM)
3956 stl_cd1400mdmisr(panelp, iobase);
3957}
3958
3959
3960
3961
3962
3963
3964
3965static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase)
3966{
3967 unsigned char svrtype;
3968
3969#if DEBUG
3970 printk("stl_cd1400echintr(panelp=%x,iobase=%x)\n", (int) panelp,
3971 iobase);
3972#endif
3973
3974 outb(SVRR, iobase);
3975 svrtype = inb(iobase + EREG_DATA);
3976 outb((SVRR + 0x80), iobase);
3977 svrtype |= inb(iobase + EREG_DATA);
3978 if (svrtype & SVRR_RX)
3979 stl_cd1400rxisr(panelp, iobase);
3980 else if (svrtype & SVRR_TX)
3981 stl_cd1400txisr(panelp, iobase);
3982 else if (svrtype & SVRR_MDM)
3983 stl_cd1400mdmisr(panelp, iobase);
3984}
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr)
3995{
3996 if (portp->brklen == 1) {
3997 outb((COR2 + portp->uartaddr), ioaddr);
3998 outb((inb(ioaddr + EREG_DATA) | COR2_ETC),
3999 (ioaddr + EREG_DATA));
4000 outb((TDR + portp->uartaddr), ioaddr);
4001 outb(ETC_CMD, (ioaddr + EREG_DATA));
4002 outb(ETC_STARTBREAK, (ioaddr + EREG_DATA));
4003 outb((SRER + portp->uartaddr), ioaddr);
4004 outb((inb(ioaddr + EREG_DATA) & ~(SRER_TXDATA | SRER_TXEMPTY)),
4005 (ioaddr + EREG_DATA));
4006 return(1);
4007 } else if (portp->brklen > 1) {
4008 outb((TDR + portp->uartaddr), ioaddr);
4009 outb(ETC_CMD, (ioaddr + EREG_DATA));
4010 outb(ETC_STOPBREAK, (ioaddr + EREG_DATA));
4011 portp->brklen = -1;
4012 return(1);
4013 } else {
4014 outb((COR2 + portp->uartaddr), ioaddr);
4015 outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC),
4016 (ioaddr + EREG_DATA));
4017 portp->brklen = 0;
4018 }
4019 return(0);
4020}
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr)
4037{
4038 stlport_t *portp;
4039 int len, stlen;
4040 char *head, *tail;
4041 unsigned char ioack, srer;
4042
4043#if DEBUG
4044 printk("stl_cd1400txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
4045#endif
4046
4047 ioack = inb(ioaddr + EREG_TXACK);
4048 if (((ioack & panelp->ackmask) != 0) ||
4049 ((ioack & ACK_TYPMASK) != ACK_TYPTX)) {
4050 printk("STALLION: bad TX interrupt ack value=%x\n", ioack);
4051 return;
4052 }
4053 portp = panelp->ports[(ioack >> 3)];
4054
4055
4056
4057
4058
4059
4060 if (portp->brklen != 0)
4061 if (stl_cd1400breakisr(portp, ioaddr))
4062 goto stl_txalldone;
4063
4064 head = portp->tx.head;
4065 tail = portp->tx.tail;
4066 len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
4067 if ((len == 0) || ((len < STL_TXBUFLOW) &&
4068 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
4069 set_bit(ASYI_TXLOW, &portp->istate);
4070 MOD_INC_USE_COUNT;
4071 if (schedule_task(&portp->tqueue) == 0)
4072 MOD_DEC_USE_COUNT;
4073 }
4074
4075 if (len == 0) {
4076 outb((SRER + portp->uartaddr), ioaddr);
4077 srer = inb(ioaddr + EREG_DATA);
4078 if (srer & SRER_TXDATA) {
4079 srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY;
4080 } else {
4081 srer &= ~(SRER_TXDATA | SRER_TXEMPTY);
4082 clear_bit(ASYI_TXBUSY, &portp->istate);
4083 }
4084 outb(srer, (ioaddr + EREG_DATA));
4085 } else {
4086 len = MIN(len, CD1400_TXFIFOSIZE);
4087 portp->stats.txtotal += len;
4088 stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
4089 outb((TDR + portp->uartaddr), ioaddr);
4090 outsb((ioaddr + EREG_DATA), tail, stlen);
4091 len -= stlen;
4092 tail += stlen;
4093 if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
4094 tail = portp->tx.buf;
4095 if (len > 0) {
4096 outsb((ioaddr + EREG_DATA), tail, len);
4097 tail += len;
4098 }
4099 portp->tx.tail = tail;
4100 }
4101
4102stl_txalldone:
4103 outb((EOSRR + portp->uartaddr), ioaddr);
4104 outb(0, (ioaddr + EREG_DATA));
4105}
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
4120{
4121 stlport_t *portp;
4122 struct tty_struct *tty;
4123 unsigned int ioack, len, buflen;
4124 unsigned char status;
4125 char ch;
4126
4127#if DEBUG
4128 printk("stl_cd1400rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
4129#endif
4130
4131 ioack = inb(ioaddr + EREG_RXACK);
4132 if ((ioack & panelp->ackmask) != 0) {
4133 printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
4134 return;
4135 }
4136 portp = panelp->ports[(ioack >> 3)];
4137 tty = portp->tty;
4138
4139 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
4140 outb((RDCR + portp->uartaddr), ioaddr);
4141 len = inb(ioaddr + EREG_DATA);
4142 if ((tty == (struct tty_struct *) NULL) ||
4143 (tty->flip.char_buf_ptr == (char *) NULL) ||
4144 ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
4145 len = MIN(len, sizeof(stl_unwanted));
4146 outb((RDSR + portp->uartaddr), ioaddr);
4147 insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
4148 portp->stats.rxlost += len;
4149 portp->stats.rxtotal += len;
4150 } else {
4151 len = MIN(len, buflen);
4152 if (len > 0) {
4153 outb((RDSR + portp->uartaddr), ioaddr);
4154 insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len);
4155 memset(tty->flip.flag_buf_ptr, 0, len);
4156 tty->flip.flag_buf_ptr += len;
4157 tty->flip.char_buf_ptr += len;
4158 tty->flip.count += len;
4159 tty_schedule_flip(tty);
4160 portp->stats.rxtotal += len;
4161 }
4162 }
4163 } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) {
4164 outb((RDSR + portp->uartaddr), ioaddr);
4165 status = inb(ioaddr + EREG_DATA);
4166 ch = inb(ioaddr + EREG_DATA);
4167 if (status & ST_PARITY)
4168 portp->stats.rxparity++;
4169 if (status & ST_FRAMING)
4170 portp->stats.rxframing++;
4171 if (status & ST_OVERRUN)
4172 portp->stats.rxoverrun++;
4173 if (status & ST_BREAK)
4174 portp->stats.rxbreaks++;
4175 if (status & ST_SCHARMASK) {
4176 if ((status & ST_SCHARMASK) == ST_SCHAR1)
4177 portp->stats.txxon++;
4178 if ((status & ST_SCHARMASK) == ST_SCHAR2)
4179 portp->stats.txxoff++;
4180 goto stl_rxalldone;
4181 }
4182 if ((tty != (struct tty_struct *) NULL) &&
4183 ((portp->rxignoremsk & status) == 0)) {
4184 if (portp->rxmarkmsk & status) {
4185 if (status & ST_BREAK) {
4186 status = TTY_BREAK;
4187 if (portp->flags & ASYNC_SAK) {
4188 do_SAK(tty);
4189 BRDENABLE(portp->brdnr, portp->pagenr);
4190 }
4191 } else if (status & ST_PARITY) {
4192 status = TTY_PARITY;
4193 } else if (status & ST_FRAMING) {
4194 status = TTY_FRAME;
4195 } else if(status & ST_OVERRUN) {
4196 status = TTY_OVERRUN;
4197 } else {
4198 status = 0;
4199 }
4200 } else {
4201 status = 0;
4202 }
4203 if (tty->flip.char_buf_ptr != (char *) NULL) {
4204 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
4205 *tty->flip.flag_buf_ptr++ = status;
4206 *tty->flip.char_buf_ptr++ = ch;
4207 tty->flip.count++;
4208 }
4209 tty_schedule_flip(tty);
4210 }
4211 }
4212 } else {
4213 printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
4214 return;
4215 }
4216
4217stl_rxalldone:
4218 outb((EOSRR + portp->uartaddr), ioaddr);
4219 outb(0, (ioaddr + EREG_DATA));
4220}
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr)
4231{
4232 stlport_t *portp;
4233 unsigned int ioack;
4234 unsigned char misr;
4235
4236#if DEBUG
4237 printk("stl_cd1400mdmisr(panelp=%x)\n", (int) panelp);
4238#endif
4239
4240 ioack = inb(ioaddr + EREG_MDACK);
4241 if (((ioack & panelp->ackmask) != 0) ||
4242 ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) {
4243 printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack);
4244 return;
4245 }
4246 portp = panelp->ports[(ioack >> 3)];
4247
4248 outb((MISR + portp->uartaddr), ioaddr);
4249 misr = inb(ioaddr + EREG_DATA);
4250 if (misr & MISR_DCD) {
4251 set_bit(ASYI_DCDCHANGE, &portp->istate);
4252 MOD_INC_USE_COUNT;
4253 if (schedule_task(&portp->tqueue) == 0)
4254 MOD_DEC_USE_COUNT;
4255 portp->stats.modem++;
4256 }
4257
4258 outb((EOSRR + portp->uartaddr), ioaddr);
4259 outb(0, (ioaddr + EREG_DATA));
4260}
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272static int stl_sc26198getreg(stlport_t *portp, int regnr)
4273{
4274 outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
4275 return(inb(portp->ioaddr + XP_DATA));
4276}
4277
4278static void stl_sc26198setreg(stlport_t *portp, int regnr, int value)
4279{
4280 outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
4281 outb(value, (portp->ioaddr + XP_DATA));
4282}
4283
4284static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value)
4285{
4286 outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
4287 if (inb(portp->ioaddr + XP_DATA) != value) {
4288 outb(value, (portp->ioaddr + XP_DATA));
4289 return(1);
4290 }
4291 return(0);
4292}
4293
4294
4295
4296
4297
4298
4299
4300static int stl_sc26198getglobreg(stlport_t *portp, int regnr)
4301{
4302 outb(regnr, (portp->ioaddr + XP_ADDR));
4303 return(inb(portp->ioaddr + XP_DATA));
4304}
4305
4306#if 0
4307static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value)
4308{
4309 outb(regnr, (portp->ioaddr + XP_ADDR));
4310 outb(value, (portp->ioaddr + XP_DATA));
4311}
4312#endif
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
4323{
4324 int chipmask, i;
4325 int nrchips, ioaddr;
4326
4327#if DEBUG
4328 printk("stl_sc26198panelinit(brdp=%x,panelp=%x)\n",
4329 (int) brdp, (int) panelp);
4330#endif
4331
4332 BRDENABLE(panelp->brdnr, panelp->pagenr);
4333
4334
4335
4336
4337 chipmask = 0;
4338 nrchips = (panelp->nrports + 4) / SC26198_PORTS;
4339 if (brdp->brdtype == BRD_ECHPCI)
4340 outb(panelp->pagenr, brdp->ioctrl);
4341
4342 for (i = 0; (i < nrchips); i++) {
4343 ioaddr = panelp->iobase + (i * 4);
4344 outb(SCCR, (ioaddr + XP_ADDR));
4345 outb(CR_RESETALL, (ioaddr + XP_DATA));
4346 outb(TSTR, (ioaddr + XP_ADDR));
4347 if (inb(ioaddr + XP_DATA) != 0) {
4348 printk("STALLION: sc26198 not responding, "
4349 "brd=%d panel=%d chip=%d\n",
4350 panelp->brdnr, panelp->panelnr, i);
4351 continue;
4352 }
4353 chipmask |= (0x1 << i);
4354 outb(GCCR, (ioaddr + XP_ADDR));
4355 outb(GCCR_IVRTYPCHANACK, (ioaddr + XP_DATA));
4356 outb(WDTRCR, (ioaddr + XP_ADDR));
4357 outb(0xff, (ioaddr + XP_DATA));
4358 }
4359
4360 BRDDISABLE(panelp->brdnr);
4361 return(chipmask);
4362}
4363
4364
4365
4366
4367
4368
4369
4370static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
4371{
4372#if DEBUG
4373 printk("stl_sc26198portinit(brdp=%x,panelp=%x,portp=%x)\n",
4374 (int) brdp, (int) panelp, (int) portp);
4375#endif
4376
4377 if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
4378 (portp == (stlport_t *) NULL))
4379 return;
4380
4381 portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4);
4382 portp->uartaddr = (portp->portnr & 0x07) << 4;
4383 portp->pagenr = panelp->pagenr;
4384 portp->hwid = 0x1;
4385
4386 BRDENABLE(portp->brdnr, portp->pagenr);
4387 stl_sc26198setreg(portp, IOPCR, IOPCR_SETSIGS);
4388 BRDDISABLE(portp->brdnr);
4389}
4390
4391
4392
4393
4394
4395
4396
4397
4398static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
4399{
4400 stlbrd_t *brdp;
4401 unsigned long flags;
4402 unsigned int baudrate;
4403 unsigned char mr0, mr1, mr2, clk;
4404 unsigned char imron, imroff, iopr, ipr;
4405
4406 mr0 = 0;
4407 mr1 = 0;
4408 mr2 = 0;
4409 clk = 0;
4410 iopr = 0;
4411 imron = 0;
4412 imroff = 0;
4413
4414 brdp = stl_brds[portp->brdnr];
4415 if (brdp == (stlbrd_t *) NULL)
4416 return;
4417
4418
4419
4420
4421
4422 portp->rxignoremsk = 0;
4423 if (tiosp->c_iflag & IGNPAR)
4424 portp->rxignoremsk |= (SR_RXPARITY | SR_RXFRAMING |
4425 SR_RXOVERRUN);
4426 if (tiosp->c_iflag & IGNBRK)
4427 portp->rxignoremsk |= SR_RXBREAK;
4428
4429 portp->rxmarkmsk = SR_RXOVERRUN;
4430 if (tiosp->c_iflag & (INPCK | PARMRK))
4431 portp->rxmarkmsk |= (SR_RXPARITY | SR_RXFRAMING);
4432 if (tiosp->c_iflag & BRKINT)
4433 portp->rxmarkmsk |= SR_RXBREAK;
4434
4435
4436
4437
4438
4439 switch (tiosp->c_cflag & CSIZE) {
4440 case CS5:
4441 mr1 |= MR1_CS5;
4442 break;
4443 case CS6:
4444 mr1 |= MR1_CS6;
4445 break;
4446 case CS7:
4447 mr1 |= MR1_CS7;
4448 break;
4449 default:
4450 mr1 |= MR1_CS8;
4451 break;
4452 }
4453
4454 if (tiosp->c_cflag & CSTOPB)
4455 mr2 |= MR2_STOP2;
4456 else
4457 mr2 |= MR2_STOP1;
4458
4459 if (tiosp->c_cflag & PARENB) {
4460 if (tiosp->c_cflag & PARODD)
4461 mr1 |= (MR1_PARENB | MR1_PARODD);
4462 else
4463 mr1 |= (MR1_PARENB | MR1_PAREVEN);
4464 } else {
4465 mr1 |= MR1_PARNONE;
4466 }
4467
4468 mr1 |= MR1_ERRBLOCK;
4469
4470
4471
4472
4473
4474
4475 mr2 |= MR2_RXFIFOHALF;
4476
4477
4478
4479
4480
4481
4482 baudrate = tiosp->c_cflag & CBAUD;
4483 if (baudrate & CBAUDEX) {
4484 baudrate &= ~CBAUDEX;
4485 if ((baudrate < 1) || (baudrate > 4))
4486 tiosp->c_cflag &= ~CBAUDEX;
4487 else
4488 baudrate += 15;
4489 }
4490 baudrate = stl_baudrates[baudrate];
4491 if ((tiosp->c_cflag & CBAUD) == B38400) {
4492 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
4493 baudrate = 57600;
4494 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
4495 baudrate = 115200;
4496 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
4497 baudrate = 230400;
4498 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
4499 baudrate = 460800;
4500 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
4501 baudrate = (portp->baud_base / portp->custom_divisor);
4502 }
4503 if (baudrate > STL_SC26198MAXBAUD)
4504 baudrate = STL_SC26198MAXBAUD;
4505
4506 if (baudrate > 0) {
4507 for (clk = 0; (clk < SC26198_NRBAUDS); clk++) {
4508 if (baudrate <= sc26198_baudtable[clk])
4509 break;
4510 }
4511 }
4512
4513
4514
4515
4516 if (tiosp->c_cflag & CLOCAL) {
4517 portp->flags &= ~ASYNC_CHECK_CD;
4518 } else {
4519 iopr |= IOPR_DCDCOS;
4520 imron |= IR_IOPORT;
4521 portp->flags |= ASYNC_CHECK_CD;
4522 }
4523
4524
4525
4526
4527
4528
4529
4530 if (tiosp->c_iflag & IXON) {
4531 mr0 |= MR0_SWFTX | MR0_SWFT;
4532 imron |= IR_XONXOFF;
4533 } else {
4534 imroff |= IR_XONXOFF;
4535 }
4536 if (tiosp->c_iflag & IXOFF)
4537 mr0 |= MR0_SWFRX;
4538
4539 if (tiosp->c_cflag & CRTSCTS) {
4540 mr2 |= MR2_AUTOCTS;
4541 mr1 |= MR1_AUTORTS;
4542 }
4543
4544
4545
4546
4547
4548
4549#if DEBUG
4550 printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
4551 portp->portnr, portp->panelnr, portp->brdnr);
4552 printk(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk);
4553 printk(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff);
4554 printk(" schr1=%x schr2=%x schr3=%x schr4=%x\n",
4555 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
4556 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
4557#endif
4558
4559 save_flags(flags);
4560 cli();
4561 BRDENABLE(portp->brdnr, portp->pagenr);
4562 stl_sc26198setreg(portp, IMR, 0);
4563 stl_sc26198updatereg(portp, MR0, mr0);
4564 stl_sc26198updatereg(portp, MR1, mr1);
4565 stl_sc26198setreg(portp, SCCR, CR_RXERRBLOCK);
4566 stl_sc26198updatereg(portp, MR2, mr2);
4567 stl_sc26198updatereg(portp, IOPIOR,
4568 ((stl_sc26198getreg(portp, IOPIOR) & ~IPR_CHANGEMASK) | iopr));
4569
4570 if (baudrate > 0) {
4571 stl_sc26198setreg(portp, TXCSR, clk);
4572 stl_sc26198setreg(portp, RXCSR, clk);
4573 }
4574
4575 stl_sc26198setreg(portp, XONCR, tiosp->c_cc[VSTART]);
4576 stl_sc26198setreg(portp, XOFFCR, tiosp->c_cc[VSTOP]);
4577
4578 ipr = stl_sc26198getreg(portp, IPR);
4579 if (ipr & IPR_DCD)
4580 portp->sigs &= ~TIOCM_CD;
4581 else
4582 portp->sigs |= TIOCM_CD;
4583
4584 portp->imr = (portp->imr & ~imroff) | imron;
4585 stl_sc26198setreg(portp, IMR, portp->imr);
4586 BRDDISABLE(portp->brdnr);
4587 restore_flags(flags);
4588}
4589
4590
4591
4592
4593
4594
4595
4596static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts)
4597{
4598 unsigned char iopioron, iopioroff;
4599 unsigned long flags;
4600
4601#if DEBUG
4602 printk("stl_sc26198setsignals(portp=%x,dtr=%d,rts=%d)\n",
4603 (int) portp, dtr, rts);
4604#endif
4605
4606 iopioron = 0;
4607 iopioroff = 0;
4608 if (dtr == 0)
4609 iopioroff |= IPR_DTR;
4610 else if (dtr > 0)
4611 iopioron |= IPR_DTR;
4612 if (rts == 0)
4613 iopioroff |= IPR_RTS;
4614 else if (rts > 0)
4615 iopioron |= IPR_RTS;
4616
4617 save_flags(flags);
4618 cli();
4619 BRDENABLE(portp->brdnr, portp->pagenr);
4620 stl_sc26198setreg(portp, IOPIOR,
4621 ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron));
4622 BRDDISABLE(portp->brdnr);
4623 restore_flags(flags);
4624}
4625
4626
4627
4628
4629
4630
4631
4632static int stl_sc26198getsignals(stlport_t *portp)
4633{
4634 unsigned char ipr;
4635 unsigned long flags;
4636 int sigs;
4637
4638#if DEBUG
4639 printk("stl_sc26198getsignals(portp=%x)\n", (int) portp);
4640#endif
4641
4642 save_flags(flags);
4643 cli();
4644 BRDENABLE(portp->brdnr, portp->pagenr);
4645 ipr = stl_sc26198getreg(portp, IPR);
4646 BRDDISABLE(portp->brdnr);
4647 restore_flags(flags);
4648
4649 sigs = 0;
4650 sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD;
4651 sigs |= (ipr & IPR_CTS) ? 0 : TIOCM_CTS;
4652 sigs |= (ipr & IPR_DTR) ? 0: TIOCM_DTR;
4653 sigs |= (ipr & IPR_RTS) ? 0: TIOCM_RTS;
4654 sigs |= TIOCM_DSR;
4655 return(sigs);
4656}
4657
4658
4659
4660
4661
4662
4663
4664static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx)
4665{
4666 unsigned char ccr;
4667 unsigned long flags;
4668
4669#if DEBUG
4670 printk("stl_sc26198enablerxtx(portp=%x,rx=%d,tx=%d)\n",
4671 (int) portp, rx, tx);
4672#endif
4673
4674 ccr = portp->crenable;
4675 if (tx == 0)
4676 ccr &= ~CR_TXENABLE;
4677 else if (tx > 0)
4678 ccr |= CR_TXENABLE;
4679 if (rx == 0)
4680 ccr &= ~CR_RXENABLE;
4681 else if (rx > 0)
4682 ccr |= CR_RXENABLE;
4683
4684 save_flags(flags);
4685 cli();
4686 BRDENABLE(portp->brdnr, portp->pagenr);
4687 stl_sc26198setreg(portp, SCCR, ccr);
4688 BRDDISABLE(portp->brdnr);
4689 portp->crenable = ccr;
4690 restore_flags(flags);
4691}
4692
4693
4694
4695
4696
4697
4698
4699static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx)
4700{
4701 unsigned char imr;
4702 unsigned long flags;
4703
4704#if DEBUG
4705 printk("stl_sc26198startrxtx(portp=%x,rx=%d,tx=%d)\n",
4706 (int) portp, rx, tx);
4707#endif
4708
4709 imr = portp->imr;
4710 if (tx == 0)
4711 imr &= ~IR_TXRDY;
4712 else if (tx == 1)
4713 imr |= IR_TXRDY;
4714 if (rx == 0)
4715 imr &= ~(IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG);
4716 else if (rx > 0)
4717 imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG;
4718
4719 save_flags(flags);
4720 cli();
4721 BRDENABLE(portp->brdnr, portp->pagenr);
4722 stl_sc26198setreg(portp, IMR, imr);
4723 BRDDISABLE(portp->brdnr);
4724 portp->imr = imr;
4725 if (tx > 0)
4726 set_bit(ASYI_TXBUSY, &portp->istate);
4727 restore_flags(flags);
4728}
4729
4730
4731
4732
4733
4734
4735
4736static void stl_sc26198disableintrs(stlport_t *portp)
4737{
4738 unsigned long flags;
4739
4740#if DEBUG
4741 printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp);
4742#endif
4743
4744 save_flags(flags);
4745 cli();
4746 BRDENABLE(portp->brdnr, portp->pagenr);
4747 portp->imr = 0;
4748 stl_sc26198setreg(portp, IMR, 0);
4749 BRDDISABLE(portp->brdnr);
4750 restore_flags(flags);
4751}
4752
4753
4754
4755static void stl_sc26198sendbreak(stlport_t *portp, int len)
4756{
4757 unsigned long flags;
4758
4759#if DEBUG
4760 printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len);
4761#endif
4762
4763 save_flags(flags);
4764 cli();
4765 BRDENABLE(portp->brdnr, portp->pagenr);
4766 if (len == 1) {
4767 stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK);
4768 portp->stats.txbreaks++;
4769 } else {
4770 stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK);
4771 }
4772 BRDDISABLE(portp->brdnr);
4773 restore_flags(flags);
4774}
4775
4776
4777
4778
4779
4780
4781
4782static void stl_sc26198flowctrl(stlport_t *portp, int state)
4783{
4784 struct tty_struct *tty;
4785 unsigned long flags;
4786 unsigned char mr0;
4787
4788#if DEBUG
4789 printk("stl_sc26198flowctrl(portp=%x,state=%x)\n", (int) portp, state);
4790#endif
4791
4792 if (portp == (stlport_t *) NULL)
4793 return;
4794 tty = portp->tty;
4795 if (tty == (struct tty_struct *) NULL)
4796 return;
4797
4798 save_flags(flags);
4799 cli();
4800 BRDENABLE(portp->brdnr, portp->pagenr);
4801
4802 if (state) {
4803 if (tty->termios->c_iflag & IXOFF) {
4804 mr0 = stl_sc26198getreg(portp, MR0);
4805 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4806 stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
4807 mr0 |= MR0_SWFRX;
4808 portp->stats.rxxon++;
4809 stl_sc26198wait(portp);
4810 stl_sc26198setreg(portp, MR0, mr0);
4811 }
4812
4813
4814
4815
4816
4817
4818 if (tty->termios->c_cflag & CRTSCTS) {
4819 stl_sc26198setreg(portp, MR1,
4820 (stl_sc26198getreg(portp, MR1) | MR1_AUTORTS));
4821 stl_sc26198setreg(portp, IOPIOR,
4822 (stl_sc26198getreg(portp, IOPIOR) | IOPR_RTS));
4823 portp->stats.rxrtson++;
4824 }
4825 } else {
4826 if (tty->termios->c_iflag & IXOFF) {
4827 mr0 = stl_sc26198getreg(portp, MR0);
4828 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4829 stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
4830 mr0 &= ~MR0_SWFRX;
4831 portp->stats.rxxoff++;
4832 stl_sc26198wait(portp);
4833 stl_sc26198setreg(portp, MR0, mr0);
4834 }
4835 if (tty->termios->c_cflag & CRTSCTS) {
4836 stl_sc26198setreg(portp, MR1,
4837 (stl_sc26198getreg(portp, MR1) & ~MR1_AUTORTS));
4838 stl_sc26198setreg(portp, IOPIOR,
4839 (stl_sc26198getreg(portp, IOPIOR) & ~IOPR_RTS));
4840 portp->stats.rxrtsoff++;
4841 }
4842 }
4843
4844 BRDDISABLE(portp->brdnr);
4845 restore_flags(flags);
4846}
4847
4848
4849
4850
4851
4852
4853
4854static void stl_sc26198sendflow(stlport_t *portp, int state)
4855{
4856 struct tty_struct *tty;
4857 unsigned long flags;
4858 unsigned char mr0;
4859
4860#if DEBUG
4861 printk("stl_sc26198sendflow(portp=%x,state=%x)\n", (int) portp, state);
4862#endif
4863
4864 if (portp == (stlport_t *) NULL)
4865 return;
4866 tty = portp->tty;
4867 if (tty == (struct tty_struct *) NULL)
4868 return;
4869
4870 save_flags(flags);
4871 cli();
4872 BRDENABLE(portp->brdnr, portp->pagenr);
4873 if (state) {
4874 mr0 = stl_sc26198getreg(portp, MR0);
4875 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4876 stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
4877 mr0 |= MR0_SWFRX;
4878 portp->stats.rxxon++;
4879 stl_sc26198wait(portp);
4880 stl_sc26198setreg(portp, MR0, mr0);
4881 } else {
4882 mr0 = stl_sc26198getreg(portp, MR0);
4883 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4884 stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
4885 mr0 &= ~MR0_SWFRX;
4886 portp->stats.rxxoff++;
4887 stl_sc26198wait(portp);
4888 stl_sc26198setreg(portp, MR0, mr0);
4889 }
4890 BRDDISABLE(portp->brdnr);
4891 restore_flags(flags);
4892}
4893
4894
4895
4896static void stl_sc26198flush(stlport_t *portp)
4897{
4898 unsigned long flags;
4899
4900#if DEBUG
4901 printk("stl_sc26198flush(portp=%x)\n", (int) portp);
4902#endif
4903
4904 if (portp == (stlport_t *) NULL)
4905 return;
4906
4907 save_flags(flags);
4908 cli();
4909 BRDENABLE(portp->brdnr, portp->pagenr);
4910 stl_sc26198setreg(portp, SCCR, CR_TXRESET);
4911 stl_sc26198setreg(portp, SCCR, portp->crenable);
4912 BRDDISABLE(portp->brdnr);
4913 portp->tx.tail = portp->tx.head;
4914 restore_flags(flags);
4915}
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927static int stl_sc26198datastate(stlport_t *portp)
4928{
4929 unsigned long flags;
4930 unsigned char sr;
4931
4932#if DEBUG
4933 printk("stl_sc26198datastate(portp=%x)\n", (int) portp);
4934#endif
4935
4936 if (portp == (stlport_t *) NULL)
4937 return(0);
4938 if (test_bit(ASYI_TXBUSY, &portp->istate))
4939 return(1);
4940
4941 save_flags(flags);
4942 cli();
4943 BRDENABLE(portp->brdnr, portp->pagenr);
4944 sr = stl_sc26198getreg(portp, SR);
4945 BRDDISABLE(portp->brdnr);
4946 restore_flags(flags);
4947
4948 return((sr & SR_TXEMPTY) ? 0 : 1);
4949}
4950
4951
4952
4953
4954
4955
4956
4957
4958static void stl_sc26198wait(stlport_t *portp)
4959{
4960 int i;
4961
4962#if DEBUG
4963 printk("stl_sc26198wait(portp=%x)\n", (int) portp);
4964#endif
4965
4966 if (portp == (stlport_t *) NULL)
4967 return;
4968
4969 for (i = 0; (i < 20); i++)
4970 stl_sc26198getglobreg(portp, TSTR);
4971}
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty)
4982{
4983 unsigned char mr0;
4984
4985 mr0 = stl_sc26198getreg(portp, MR0);
4986 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4987 stl_sc26198setreg(portp, SCCR, CR_HOSTXON);
4988 stl_sc26198wait(portp);
4989 stl_sc26198setreg(portp, MR0, mr0);
4990 clear_bit(ASYI_TXFLOWED, &portp->istate);
4991}
4992
4993
4994
4995
4996
4997
4998
4999static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase)
5000{
5001 stlport_t *portp;
5002 unsigned int iack;
5003
5004
5005
5006
5007
5008 outb(0, (iobase + 1));
5009
5010 iack = inb(iobase + XP_IACK);
5011 portp = panelp->ports[(iack & IVR_CHANMASK) + ((iobase & 0x4) << 1)];
5012
5013 if (iack & IVR_RXDATA)
5014 stl_sc26198rxisr(portp, iack);
5015 else if (iack & IVR_TXDATA)
5016 stl_sc26198txisr(portp);
5017 else
5018 stl_sc26198otherisr(portp, iack);
5019}
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033static void stl_sc26198txisr(stlport_t *portp)
5034{
5035 unsigned int ioaddr;
5036 unsigned char mr0;
5037 int len, stlen;
5038 char *head, *tail;
5039
5040#if DEBUG
5041 printk("stl_sc26198txisr(portp=%x)\n", (int) portp);
5042#endif
5043
5044 ioaddr = portp->ioaddr;
5045 head = portp->tx.head;
5046 tail = portp->tx.tail;
5047 len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
5048 if ((len == 0) || ((len < STL_TXBUFLOW) &&
5049 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
5050 set_bit(ASYI_TXLOW, &portp->istate);
5051 MOD_INC_USE_COUNT;
5052 if (schedule_task(&portp->tqueue) == 0)
5053 MOD_DEC_USE_COUNT;
5054 }
5055
5056 if (len == 0) {
5057 outb((MR0 | portp->uartaddr), (ioaddr + XP_ADDR));
5058 mr0 = inb(ioaddr + XP_DATA);
5059 if ((mr0 & MR0_TXMASK) == MR0_TXEMPTY) {
5060 portp->imr &= ~IR_TXRDY;
5061 outb((IMR | portp->uartaddr), (ioaddr + XP_ADDR));
5062 outb(portp->imr, (ioaddr + XP_DATA));
5063 clear_bit(ASYI_TXBUSY, &portp->istate);
5064 } else {
5065 mr0 |= ((mr0 & ~MR0_TXMASK) | MR0_TXEMPTY);
5066 outb(mr0, (ioaddr + XP_DATA));
5067 }
5068 } else {
5069 len = MIN(len, SC26198_TXFIFOSIZE);
5070 portp->stats.txtotal += len;
5071 stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
5072 outb(GTXFIFO, (ioaddr + XP_ADDR));
5073 outsb((ioaddr + XP_DATA), tail, stlen);
5074 len -= stlen;
5075 tail += stlen;
5076 if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
5077 tail = portp->tx.buf;
5078 if (len > 0) {
5079 outsb((ioaddr + XP_DATA), tail, len);
5080 tail += len;
5081 }
5082 portp->tx.tail = tail;
5083 }
5084}
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
5099{
5100 struct tty_struct *tty;
5101 unsigned int len, buflen, ioaddr;
5102
5103#if DEBUG
5104 printk("stl_sc26198rxisr(portp=%x,iack=%x)\n", (int) portp, iack);
5105#endif
5106
5107 tty = portp->tty;
5108 ioaddr = portp->ioaddr;
5109 outb(GIBCR, (ioaddr + XP_ADDR));
5110 len = inb(ioaddr + XP_DATA) + 1;
5111
5112 if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
5113 if ((tty == (struct tty_struct *) NULL) ||
5114 (tty->flip.char_buf_ptr == (char *) NULL) ||
5115 ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
5116 len = MIN(len, sizeof(stl_unwanted));
5117 outb(GRXFIFO, (ioaddr + XP_ADDR));
5118 insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
5119 portp->stats.rxlost += len;
5120 portp->stats.rxtotal += len;
5121 } else {
5122 len = MIN(len, buflen);
5123 if (len > 0) {
5124 outb(GRXFIFO, (ioaddr + XP_ADDR));
5125 insb((ioaddr + XP_DATA), tty->flip.char_buf_ptr, len);
5126 memset(tty->flip.flag_buf_ptr, 0, len);
5127 tty->flip.flag_buf_ptr += len;
5128 tty->flip.char_buf_ptr += len;
5129 tty->flip.count += len;
5130 tty_schedule_flip(tty);
5131 portp->stats.rxtotal += len;
5132 }
5133 }
5134 } else {
5135 stl_sc26198rxbadchars(portp);
5136 }
5137
5138
5139
5140
5141
5142
5143 if (test_bit(ASYI_TXFLOWED, &portp->istate)) {
5144 if ((tty != (struct tty_struct *) NULL) &&
5145 (tty->termios != (struct termios *) NULL) &&
5146 (tty->termios->c_iflag & IXANY)) {
5147 stl_sc26198txunflow(portp, tty);
5148 }
5149 }
5150}
5151
5152
5153
5154
5155
5156
5157
5158static void inline stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch)
5159{
5160 struct tty_struct *tty;
5161 unsigned int ioaddr;
5162
5163 tty = portp->tty;
5164 ioaddr = portp->ioaddr;
5165
5166 if (status & SR_RXPARITY)
5167 portp->stats.rxparity++;
5168 if (status & SR_RXFRAMING)
5169 portp->stats.rxframing++;
5170 if (status & SR_RXOVERRUN)
5171 portp->stats.rxoverrun++;
5172 if (status & SR_RXBREAK)
5173 portp->stats.rxbreaks++;
5174
5175 if ((tty != (struct tty_struct *) NULL) &&
5176 ((portp->rxignoremsk & status) == 0)) {
5177 if (portp->rxmarkmsk & status) {
5178 if (status & SR_RXBREAK) {
5179 status = TTY_BREAK;
5180 if (portp->flags & ASYNC_SAK) {
5181 do_SAK(tty);
5182 BRDENABLE(portp->brdnr, portp->pagenr);
5183 }
5184 } else if (status & SR_RXPARITY) {
5185 status = TTY_PARITY;
5186 } else if (status & SR_RXFRAMING) {
5187 status = TTY_FRAME;
5188 } else if(status & SR_RXOVERRUN) {
5189 status = TTY_OVERRUN;
5190 } else {
5191 status = 0;
5192 }
5193 } else {
5194 status = 0;
5195 }
5196
5197 if (tty->flip.char_buf_ptr != (char *) NULL) {
5198 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
5199 *tty->flip.flag_buf_ptr++ = status;
5200 *tty->flip.char_buf_ptr++ = ch;
5201 tty->flip.count++;
5202 }
5203 tty_schedule_flip(tty);
5204 }
5205
5206 if (status == 0)
5207 portp->stats.rxtotal++;
5208 }
5209}
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222static void stl_sc26198rxbadchars(stlport_t *portp)
5223{
5224 unsigned char status, mr1;
5225 char ch;
5226
5227
5228
5229
5230
5231 mr1 = stl_sc26198getreg(portp, MR1);
5232 stl_sc26198setreg(portp, MR1, (mr1 & ~MR1_ERRBLOCK));
5233
5234 while ((status = stl_sc26198getreg(portp, SR)) & SR_RXRDY) {
5235 stl_sc26198setreg(portp, SCCR, CR_CLEARRXERR);
5236 ch = stl_sc26198getreg(portp, RXFIFO);
5237 stl_sc26198rxbadch(portp, status, ch);
5238 }
5239
5240
5241
5242
5243
5244 stl_sc26198setreg(portp, MR1, mr1);
5245}
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack)
5256{
5257 unsigned char cir, ipr, xisr;
5258
5259#if DEBUG
5260 printk("stl_sc26198otherisr(portp=%x,iack=%x)\n", (int) portp, iack);
5261#endif
5262
5263 cir = stl_sc26198getglobreg(portp, CIR);
5264
5265 switch (cir & CIR_SUBTYPEMASK) {
5266 case CIR_SUBCOS:
5267 ipr = stl_sc26198getreg(portp, IPR);
5268 if (ipr & IPR_DCDCHANGE) {
5269 set_bit(ASYI_DCDCHANGE, &portp->istate);
5270 MOD_INC_USE_COUNT;
5271 if (schedule_task(&portp->tqueue) == 0)
5272 MOD_DEC_USE_COUNT;
5273 portp->stats.modem++;
5274 }
5275 break;
5276 case CIR_SUBXONXOFF:
5277 xisr = stl_sc26198getreg(portp, XISR);
5278 if (xisr & XISR_RXXONGOT) {
5279 set_bit(ASYI_TXFLOWED, &portp->istate);
5280 portp->stats.txxoff++;
5281 }
5282 if (xisr & XISR_RXXOFFGOT) {
5283 clear_bit(ASYI_TXFLOWED, &portp->istate);
5284 portp->stats.txxon++;
5285 }
5286 break;
5287 case CIR_SUBBREAK:
5288 stl_sc26198setreg(portp, SCCR, CR_BREAKRESET);
5289 stl_sc26198rxbadchars(portp);
5290 break;
5291 default:
5292 break;
5293 }
5294}
5295
5296
5297