blob: 6a6e5124a5fa9fea293f17ef6e8628615470bda4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*****************************************************************************/
2
3/*
4 * stallion.c -- stallion multiport serial driver.
5 *
6 * Copyright (C) 1996-1999 Stallion Technologies
7 * Copyright (C) 1994-1996 Greg Ungerer.
8 *
9 * This code is loosely based on the Linux serial driver, written by
10 * Linus Torvalds, Theodore T'so and others.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27/*****************************************************************************/
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/module.h>
30#include <linux/slab.h>
31#include <linux/interrupt.h>
32#include <linux/tty.h>
33#include <linux/tty_flip.h>
34#include <linux/serial.h>
35#include <linux/cd1400.h>
36#include <linux/sc26198.h>
37#include <linux/comstats.h>
38#include <linux/stallion.h>
39#include <linux/ioport.h>
40#include <linux/init.h>
41#include <linux/smp_lock.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/device.h>
43#include <linux/delay.h>
44
45#include <asm/io.h>
46#include <asm/uaccess.h>
47
48#ifdef CONFIG_PCI
49#include <linux/pci.h>
50#endif
51
52/*****************************************************************************/
53
54/*
55 * Define different board types. Use the standard Stallion "assigned"
56 * board numbers. Boards supported in this driver are abbreviated as
57 * EIO = EasyIO and ECH = EasyConnection 8/32.
58 */
59#define BRD_EASYIO 20
60#define BRD_ECH 21
61#define BRD_ECHMC 22
62#define BRD_ECHPCI 26
63#define BRD_ECH64PCI 27
64#define BRD_EASYIOPCI 28
65
66/*
67 * Define a configuration structure to hold the board configuration.
68 * Need to set this up in the code (for now) with the boards that are
69 * to be configured into the system. This is what needs to be modified
70 * when adding/removing/modifying boards. Each line entry in the
71 * stl_brdconf[] array is a board. Each line contains io/irq/memory
72 * ranges for that board (as well as what type of board it is).
73 * Some examples:
74 * { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },
75 * This line would configure an EasyIO board (4 or 8, no difference),
76 * at io address 2a0 and irq 10.
77 * Another example:
78 * { BRD_ECH, 0x2a8, 0x280, 0, 12, 0 },
79 * This line will configure an EasyConnection 8/32 board at primary io
80 * address 2a8, secondary io address 280 and irq 12.
81 * Enter as many lines into this array as you want (only the first 4
82 * will actually be used!). Any combination of EasyIO and EasyConnection
83 * boards can be specified. EasyConnection 8/32 boards can share their
84 * secondary io addresses between each other.
85 *
86 * NOTE: there is no need to put any entries in this table for PCI
87 * boards. They will be found automatically by the driver - provided
88 * PCI BIOS32 support is compiled into the kernel.
89 */
90
91typedef struct {
92 int brdtype;
93 int ioaddr1;
94 int ioaddr2;
95 unsigned long memaddr;
96 int irq;
97 int irqtype;
98} stlconf_t;
99
100static stlconf_t stl_brdconf[] = {
101 /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/
102};
103
Tobias Klauserfe971072006-01-09 20:54:02 -0800104static int stl_nrbrds = ARRAY_SIZE(stl_brdconf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106/*****************************************************************************/
107
108/*
109 * Define some important driver characteristics. Device major numbers
110 * allocated as per Linux Device Registry.
111 */
112#ifndef STL_SIOMEMMAJOR
113#define STL_SIOMEMMAJOR 28
114#endif
115#ifndef STL_SERIALMAJOR
116#define STL_SERIALMAJOR 24
117#endif
118#ifndef STL_CALLOUTMAJOR
119#define STL_CALLOUTMAJOR 25
120#endif
121
122/*
123 * Set the TX buffer size. Bigger is better, but we don't want
124 * to chew too much memory with buffers!
125 */
126#define STL_TXBUFLOW 512
127#define STL_TXBUFSIZE 4096
128
129/*****************************************************************************/
130
131/*
132 * Define our local driver identity first. Set up stuff to deal with
133 * all the local structures required by a serial tty driver.
134 */
135static char *stl_drvtitle = "Stallion Multiport Serial Driver";
136static char *stl_drvname = "stallion";
137static char *stl_drvversion = "5.6.0";
138
139static struct tty_driver *stl_serial;
140
141/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 * Define a local default termios struct. All ports will be created
143 * with this termios initially. Basically all it defines is a raw port
144 * at 9600, 8 data bits, 1 stop bit.
145 */
146static struct termios stl_deftermios = {
147 .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
148 .c_cc = INIT_C_CC,
149};
150
151/*
152 * Define global stats structures. Not used often, and can be
153 * re-used for each stats call.
154 */
155static comstats_t stl_comstats;
156static combrd_t stl_brdstats;
157static stlbrd_t stl_dummybrd;
158static stlport_t stl_dummyport;
159
160/*
161 * Define global place to put buffer overflow characters.
162 */
163static char stl_unwanted[SC26198_RXFIFOSIZE];
164
165/*****************************************************************************/
166
167static stlbrd_t *stl_brds[STL_MAXBRDS];
168
169/*
170 * Per board state flags. Used with the state field of the board struct.
171 * Not really much here!
172 */
173#define BRD_FOUND 0x1
174
175/*
176 * Define the port structure istate flags. These set of flags are
177 * modified at interrupt time - so setting and reseting them needs
178 * to be atomic. Use the bit clear/setting routines for this.
179 */
180#define ASYI_TXBUSY 1
181#define ASYI_TXLOW 2
182#define ASYI_DCDCHANGE 3
183#define ASYI_TXFLOWED 4
184
185/*
186 * Define an array of board names as printable strings. Handy for
187 * referencing boards when printing trace and stuff.
188 */
189static char *stl_brdnames[] = {
Jiri Slaby615e4a72006-12-08 02:38:38 -0800190 NULL,
191 NULL,
192 NULL,
193 NULL,
194 NULL,
195 NULL,
196 NULL,
197 NULL,
198 NULL,
199 NULL,
200 NULL,
201 NULL,
202 NULL,
203 NULL,
204 NULL,
205 NULL,
206 NULL,
207 NULL,
208 NULL,
209 NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 "EasyIO",
211 "EC8/32-AT",
212 "EC8/32-MC",
Jiri Slaby615e4a72006-12-08 02:38:38 -0800213 NULL,
214 NULL,
215 NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 "EC8/32-PCI",
217 "EC8/64-PCI",
218 "EasyIO-PCI",
219};
220
221/*****************************************************************************/
222
223/*
224 * Define some string labels for arguments passed from the module
225 * load line. These allow for easy board definitions, and easy
226 * modification of the io, memory and irq resoucres.
227 */
228static int stl_nargs = 0;
229static char *board0[4];
230static char *board1[4];
231static char *board2[4];
232static char *board3[4];
233
234static char **stl_brdsp[] = {
235 (char **) &board0,
236 (char **) &board1,
237 (char **) &board2,
238 (char **) &board3
239};
240
241/*
242 * Define a set of common board names, and types. This is used to
243 * parse any module arguments.
244 */
245
246typedef struct stlbrdtype {
247 char *name;
248 int type;
249} stlbrdtype_t;
250
251static stlbrdtype_t stl_brdstr[] = {
252 { "easyio", BRD_EASYIO },
253 { "eio", BRD_EASYIO },
254 { "20", BRD_EASYIO },
255 { "ec8/32", BRD_ECH },
256 { "ec8/32-at", BRD_ECH },
257 { "ec8/32-isa", BRD_ECH },
258 { "ech", BRD_ECH },
259 { "echat", BRD_ECH },
260 { "21", BRD_ECH },
261 { "ec8/32-mc", BRD_ECHMC },
262 { "ec8/32-mca", BRD_ECHMC },
263 { "echmc", BRD_ECHMC },
264 { "echmca", BRD_ECHMC },
265 { "22", BRD_ECHMC },
266 { "ec8/32-pc", BRD_ECHPCI },
267 { "ec8/32-pci", BRD_ECHPCI },
268 { "26", BRD_ECHPCI },
269 { "ec8/64-pc", BRD_ECH64PCI },
270 { "ec8/64-pci", BRD_ECH64PCI },
271 { "ech-pci", BRD_ECH64PCI },
272 { "echpci", BRD_ECH64PCI },
273 { "echpc", BRD_ECH64PCI },
274 { "27", BRD_ECH64PCI },
275 { "easyio-pc", BRD_EASYIOPCI },
276 { "easyio-pci", BRD_EASYIOPCI },
277 { "eio-pci", BRD_EASYIOPCI },
278 { "eiopci", BRD_EASYIOPCI },
279 { "28", BRD_EASYIOPCI },
280};
281
282/*
283 * Define the module agruments.
284 */
285MODULE_AUTHOR("Greg Ungerer");
286MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
287MODULE_LICENSE("GPL");
288
289module_param_array(board0, charp, &stl_nargs, 0);
290MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]");
291module_param_array(board1, charp, &stl_nargs, 0);
292MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]");
293module_param_array(board2, charp, &stl_nargs, 0);
294MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]");
295module_param_array(board3, charp, &stl_nargs, 0);
296MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]");
297
298/*****************************************************************************/
299
300/*
301 * Hardware ID bits for the EasyIO and ECH boards. These defines apply
302 * to the directly accessible io ports of these boards (not the uarts -
303 * they are in cd1400.h and sc26198.h).
304 */
305#define EIO_8PORTRS 0x04
306#define EIO_4PORTRS 0x05
307#define EIO_8PORTDI 0x00
308#define EIO_8PORTM 0x06
309#define EIO_MK3 0x03
310#define EIO_IDBITMASK 0x07
311
312#define EIO_BRDMASK 0xf0
313#define ID_BRD4 0x10
314#define ID_BRD8 0x20
315#define ID_BRD16 0x30
316
317#define EIO_INTRPEND 0x08
318#define EIO_INTEDGE 0x00
319#define EIO_INTLEVEL 0x08
320#define EIO_0WS 0x10
321
322#define ECH_ID 0xa0
323#define ECH_IDBITMASK 0xe0
324#define ECH_BRDENABLE 0x08
325#define ECH_BRDDISABLE 0x00
326#define ECH_INTENABLE 0x01
327#define ECH_INTDISABLE 0x00
328#define ECH_INTLEVEL 0x02
329#define ECH_INTEDGE 0x00
330#define ECH_INTRPEND 0x01
331#define ECH_BRDRESET 0x01
332
333#define ECHMC_INTENABLE 0x01
334#define ECHMC_BRDRESET 0x02
335
336#define ECH_PNLSTATUS 2
337#define ECH_PNL16PORT 0x20
338#define ECH_PNLIDMASK 0x07
339#define ECH_PNLXPID 0x40
340#define ECH_PNLINTRPEND 0x80
341
342#define ECH_ADDR2MASK 0x1e0
343
344/*
345 * Define the vector mapping bits for the programmable interrupt board
346 * hardware. These bits encode the interrupt for the board to use - it
347 * is software selectable (except the EIO-8M).
348 */
349static unsigned char stl_vecmap[] = {
350 0xff, 0xff, 0xff, 0x04, 0x06, 0x05, 0xff, 0x07,
351 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03
352};
353
354/*
Alan Coxb65b5b52006-06-27 02:54:05 -0700355 * Lock ordering is that you may not take stallion_lock holding
356 * brd_lock.
357 */
358
359static spinlock_t brd_lock; /* Guard the board mapping */
360static spinlock_t stallion_lock; /* Guard the tty driver */
361
362/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 * Set up enable and disable macros for the ECH boards. They require
364 * the secondary io address space to be activated and deactivated.
365 * This way all ECH boards can share their secondary io region.
366 * If this is an ECH-PCI board then also need to set the page pointer
367 * to point to the correct page.
368 */
369#define BRDENABLE(brdnr,pagenr) \
370 if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \
371 outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDENABLE), \
372 stl_brds[(brdnr)]->ioctrl); \
373 else if (stl_brds[(brdnr)]->brdtype == BRD_ECHPCI) \
374 outb((pagenr), stl_brds[(brdnr)]->ioctrl);
375
376#define BRDDISABLE(brdnr) \
377 if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \
378 outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE), \
379 stl_brds[(brdnr)]->ioctrl);
380
381#define STL_CD1400MAXBAUD 230400
382#define STL_SC26198MAXBAUD 460800
383
384#define STL_BAUDBASE 115200
385#define STL_CLOSEDELAY (5 * HZ / 10)
386
387/*****************************************************************************/
388
389#ifdef CONFIG_PCI
390
391/*
392 * Define the Stallion PCI vendor and device IDs.
393 */
394#ifndef PCI_VENDOR_ID_STALLION
395#define PCI_VENDOR_ID_STALLION 0x124d
396#endif
397#ifndef PCI_DEVICE_ID_ECHPCI832
398#define PCI_DEVICE_ID_ECHPCI832 0x0000
399#endif
400#ifndef PCI_DEVICE_ID_ECHPCI864
401#define PCI_DEVICE_ID_ECHPCI864 0x0002
402#endif
403#ifndef PCI_DEVICE_ID_EIOPCI
404#define PCI_DEVICE_ID_EIOPCI 0x0003
405#endif
406
407/*
408 * Define structure to hold all Stallion PCI boards.
409 */
410typedef struct stlpcibrd {
411 unsigned short vendid;
412 unsigned short devid;
413 int brdtype;
414} stlpcibrd_t;
415
416static stlpcibrd_t stl_pcibrds[] = {
417 { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864, BRD_ECH64PCI },
418 { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI, BRD_EASYIOPCI },
419 { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832, BRD_ECHPCI },
420 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI },
421};
422
Tobias Klauserfe971072006-01-09 20:54:02 -0800423static int stl_nrpcibrds = ARRAY_SIZE(stl_pcibrds);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
425#endif
426
427/*****************************************************************************/
428
429/*
430 * Define macros to extract a brd/port number from a minor number.
431 */
432#define MINOR2BRD(min) (((min) & 0xc0) >> 6)
433#define MINOR2PORT(min) ((min) & 0x3f)
434
435/*
436 * Define a baud rate table that converts termios baud rate selector
437 * into the actual baud rate value. All baud rate calculations are
438 * based on the actual baud rate required.
439 */
440static unsigned int stl_baudrates[] = {
441 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
442 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
443};
444
445/*
446 * Define some handy local macros...
447 */
448#undef MIN
449#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
450
451#undef TOLOWER
452#define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
453
454/*****************************************************************************/
455
456/*
457 * Declare all those functions in this driver!
458 */
459
460static void stl_argbrds(void);
461static int stl_parsebrd(stlconf_t *confp, char **argp);
462
463static unsigned long stl_atol(char *str);
464
Adrian Bunk408b6642005-05-01 08:59:29 -0700465static int stl_init(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466static int stl_open(struct tty_struct *tty, struct file *filp);
467static void stl_close(struct tty_struct *tty, struct file *filp);
468static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count);
469static void stl_putchar(struct tty_struct *tty, unsigned char ch);
470static void stl_flushchars(struct tty_struct *tty);
471static int stl_writeroom(struct tty_struct *tty);
472static int stl_charsinbuffer(struct tty_struct *tty);
473static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
474static void stl_settermios(struct tty_struct *tty, struct termios *old);
475static void stl_throttle(struct tty_struct *tty);
476static void stl_unthrottle(struct tty_struct *tty);
477static void stl_stop(struct tty_struct *tty);
478static void stl_start(struct tty_struct *tty);
479static void stl_flushbuffer(struct tty_struct *tty);
480static void stl_breakctl(struct tty_struct *tty, int state);
481static void stl_waituntilsent(struct tty_struct *tty, int timeout);
482static void stl_sendxchar(struct tty_struct *tty, char ch);
483static void stl_hangup(struct tty_struct *tty);
484static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
485static int stl_portinfo(stlport_t *portp, int portnr, char *pos);
486static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data);
487
488static int stl_brdinit(stlbrd_t *brdp);
489static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
490static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp);
491static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp);
492static int stl_getbrdstats(combrd_t __user *bp);
493static int stl_getportstats(stlport_t *portp, comstats_t __user *cp);
494static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp);
495static int stl_getportstruct(stlport_t __user *arg);
496static int stl_getbrdstruct(stlbrd_t __user *arg);
497static int stl_waitcarrier(stlport_t *portp, struct file *filp);
498static int stl_eiointr(stlbrd_t *brdp);
499static int stl_echatintr(stlbrd_t *brdp);
500static int stl_echmcaintr(stlbrd_t *brdp);
501static int stl_echpciintr(stlbrd_t *brdp);
502static int stl_echpci64intr(stlbrd_t *brdp);
Al Viro3e577a82006-12-06 18:41:45 +0000503static void stl_offintr(struct work_struct *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504static stlbrd_t *stl_allocbrd(void);
505static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
506
507static inline int stl_initbrds(void);
508static inline int stl_initeio(stlbrd_t *brdp);
509static inline int stl_initech(stlbrd_t *brdp);
510static inline int stl_getbrdnr(void);
511
512#ifdef CONFIG_PCI
513static inline int stl_findpcibrds(void);
514static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp);
515#endif
516
517/*
518 * CD1400 uart specific handling functions.
519 */
520static void stl_cd1400setreg(stlport_t *portp, int regnr, int value);
521static int stl_cd1400getreg(stlport_t *portp, int regnr);
522static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value);
523static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
524static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
525static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp);
526static int stl_cd1400getsignals(stlport_t *portp);
527static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts);
528static void stl_cd1400ccrwait(stlport_t *portp);
529static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx);
530static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx);
531static void stl_cd1400disableintrs(stlport_t *portp);
532static void stl_cd1400sendbreak(stlport_t *portp, int len);
533static void stl_cd1400flowctrl(stlport_t *portp, int state);
534static void stl_cd1400sendflow(stlport_t *portp, int state);
535static void stl_cd1400flush(stlport_t *portp);
536static int stl_cd1400datastate(stlport_t *portp);
537static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase);
538static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase);
539static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr);
540static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr);
541static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr);
542
543static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr);
544
545/*
546 * SC26198 uart specific handling functions.
547 */
548static void stl_sc26198setreg(stlport_t *portp, int regnr, int value);
549static int stl_sc26198getreg(stlport_t *portp, int regnr);
550static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value);
551static int stl_sc26198getglobreg(stlport_t *portp, int regnr);
552static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
553static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
554static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp);
555static int stl_sc26198getsignals(stlport_t *portp);
556static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts);
557static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx);
558static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx);
559static void stl_sc26198disableintrs(stlport_t *portp);
560static void stl_sc26198sendbreak(stlport_t *portp, int len);
561static void stl_sc26198flowctrl(stlport_t *portp, int state);
562static void stl_sc26198sendflow(stlport_t *portp, int state);
563static void stl_sc26198flush(stlport_t *portp);
564static int stl_sc26198datastate(stlport_t *portp);
565static void stl_sc26198wait(stlport_t *portp);
566static void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty);
567static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase);
568static void stl_sc26198txisr(stlport_t *port);
569static void stl_sc26198rxisr(stlport_t *port, unsigned int iack);
570static void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch);
571static void stl_sc26198rxbadchars(stlport_t *portp);
572static void stl_sc26198otherisr(stlport_t *port, unsigned int iack);
573
574/*****************************************************************************/
575
576/*
577 * Generic UART support structure.
578 */
579typedef struct uart {
580 int (*panelinit)(stlbrd_t *brdp, stlpanel_t *panelp);
581 void (*portinit)(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
582 void (*setport)(stlport_t *portp, struct termios *tiosp);
583 int (*getsignals)(stlport_t *portp);
584 void (*setsignals)(stlport_t *portp, int dtr, int rts);
585 void (*enablerxtx)(stlport_t *portp, int rx, int tx);
586 void (*startrxtx)(stlport_t *portp, int rx, int tx);
587 void (*disableintrs)(stlport_t *portp);
588 void (*sendbreak)(stlport_t *portp, int len);
589 void (*flowctrl)(stlport_t *portp, int state);
590 void (*sendflow)(stlport_t *portp, int state);
591 void (*flush)(stlport_t *portp);
592 int (*datastate)(stlport_t *portp);
593 void (*intr)(stlpanel_t *panelp, unsigned int iobase);
594} uart_t;
595
596/*
597 * Define some macros to make calling these functions nice and clean.
598 */
599#define stl_panelinit (* ((uart_t *) panelp->uartp)->panelinit)
600#define stl_portinit (* ((uart_t *) portp->uartp)->portinit)
601#define stl_setport (* ((uart_t *) portp->uartp)->setport)
602#define stl_getsignals (* ((uart_t *) portp->uartp)->getsignals)
603#define stl_setsignals (* ((uart_t *) portp->uartp)->setsignals)
604#define stl_enablerxtx (* ((uart_t *) portp->uartp)->enablerxtx)
605#define stl_startrxtx (* ((uart_t *) portp->uartp)->startrxtx)
606#define stl_disableintrs (* ((uart_t *) portp->uartp)->disableintrs)
607#define stl_sendbreak (* ((uart_t *) portp->uartp)->sendbreak)
608#define stl_flowctrl (* ((uart_t *) portp->uartp)->flowctrl)
609#define stl_sendflow (* ((uart_t *) portp->uartp)->sendflow)
610#define stl_flush (* ((uart_t *) portp->uartp)->flush)
611#define stl_datastate (* ((uart_t *) portp->uartp)->datastate)
612
613/*****************************************************************************/
614
615/*
616 * CD1400 UART specific data initialization.
617 */
618static uart_t stl_cd1400uart = {
619 stl_cd1400panelinit,
620 stl_cd1400portinit,
621 stl_cd1400setport,
622 stl_cd1400getsignals,
623 stl_cd1400setsignals,
624 stl_cd1400enablerxtx,
625 stl_cd1400startrxtx,
626 stl_cd1400disableintrs,
627 stl_cd1400sendbreak,
628 stl_cd1400flowctrl,
629 stl_cd1400sendflow,
630 stl_cd1400flush,
631 stl_cd1400datastate,
632 stl_cd1400eiointr
633};
634
635/*
636 * Define the offsets within the register bank of a cd1400 based panel.
637 * These io address offsets are common to the EasyIO board as well.
638 */
639#define EREG_ADDR 0
640#define EREG_DATA 4
641#define EREG_RXACK 5
642#define EREG_TXACK 6
643#define EREG_MDACK 7
644
645#define EREG_BANKSIZE 8
646
647#define CD1400_CLK 25000000
648#define CD1400_CLK8M 20000000
649
650/*
651 * Define the cd1400 baud rate clocks. These are used when calculating
652 * what clock and divisor to use for the required baud rate. Also
653 * define the maximum baud rate allowed, and the default base baud.
654 */
655static int stl_cd1400clkdivs[] = {
656 CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4
657};
658
659/*****************************************************************************/
660
661/*
662 * SC26198 UART specific data initization.
663 */
664static uart_t stl_sc26198uart = {
665 stl_sc26198panelinit,
666 stl_sc26198portinit,
667 stl_sc26198setport,
668 stl_sc26198getsignals,
669 stl_sc26198setsignals,
670 stl_sc26198enablerxtx,
671 stl_sc26198startrxtx,
672 stl_sc26198disableintrs,
673 stl_sc26198sendbreak,
674 stl_sc26198flowctrl,
675 stl_sc26198sendflow,
676 stl_sc26198flush,
677 stl_sc26198datastate,
678 stl_sc26198intr
679};
680
681/*
682 * Define the offsets within the register bank of a sc26198 based panel.
683 */
684#define XP_DATA 0
685#define XP_ADDR 1
686#define XP_MODID 2
687#define XP_STATUS 2
688#define XP_IACK 3
689
690#define XP_BANKSIZE 4
691
692/*
693 * Define the sc26198 baud rate table. Offsets within the table
694 * represent the actual baud rate selector of sc26198 registers.
695 */
696static unsigned int sc26198_baudtable[] = {
697 50, 75, 150, 200, 300, 450, 600, 900, 1200, 1800, 2400, 3600,
698 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200,
699 230400, 460800, 921600
700};
701
Tobias Klauserfe971072006-01-09 20:54:02 -0800702#define SC26198_NRBAUDS ARRAY_SIZE(sc26198_baudtable)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703
704/*****************************************************************************/
705
706/*
707 * Define the driver info for a user level control device. Used mainly
708 * to get at port stats - only not using the port device itself.
709 */
Arjan van de Ven62322d22006-07-03 00:24:21 -0700710static const struct file_operations stl_fsiomem = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 .owner = THIS_MODULE,
712 .ioctl = stl_memioctl,
713};
714
715/*****************************************************************************/
716
gregkh@suse.deca8eca62005-03-23 09:53:09 -0800717static struct class *stallion_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
719/*
720 * Loadable module initialization stuff.
721 */
722
723static int __init stallion_module_init(void)
724{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 stl_init();
Jesper Juhl014c2542006-01-15 02:37:08 +0100726 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727}
728
729/*****************************************************************************/
730
731static void __exit stallion_module_exit(void)
732{
733 stlbrd_t *brdp;
734 stlpanel_t *panelp;
735 stlport_t *portp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 int i, j, k;
737
Jiri Slabya0564e12006-12-08 02:38:37 -0800738 pr_debug("cleanup_module()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739
740 printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle,
741 stl_drvversion);
742
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743/*
744 * Free up all allocated resources used by the ports. This includes
745 * memory and interrupts. As part of this process we will also do
746 * a hangup on every open port - to try to flush out any processes
747 * hanging onto ports.
748 */
749 i = tty_unregister_driver(stl_serial);
750 put_tty_driver(stl_serial);
751 if (i) {
752 printk("STALLION: failed to un-register tty driver, "
753 "errno=%d\n", -i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 return;
755 }
Greg Kroah-Hartman8ab5e4c2005-06-20 21:15:16 -0700756 for (i = 0; i < 4; i++)
gregkh@suse.deca8eca62005-03-23 09:53:09 -0800757 class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
759 printk("STALLION: failed to un-register serial memory device, "
760 "errno=%d\n", -i);
gregkh@suse.deca8eca62005-03-23 09:53:09 -0800761 class_destroy(stallion_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 for (i = 0; (i < stl_nrbrds); i++) {
Jiri Slaby615e4a72006-12-08 02:38:38 -0800764 if ((brdp = stl_brds[i]) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 continue;
766
767 free_irq(brdp->irq, brdp);
768
769 for (j = 0; (j < STL_MAXPANELS); j++) {
770 panelp = brdp->panels[j];
Jiri Slaby615e4a72006-12-08 02:38:38 -0800771 if (panelp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 continue;
773 for (k = 0; (k < STL_PORTSPERPANEL); k++) {
774 portp = panelp->ports[k];
Jiri Slaby615e4a72006-12-08 02:38:38 -0800775 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 continue;
Jiri Slaby615e4a72006-12-08 02:38:38 -0800777 if (portp->tty != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 stl_hangup(portp->tty);
Jesper Juhl735d5662005-11-07 01:01:29 -0800779 kfree(portp->tx.buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 kfree(portp);
781 }
782 kfree(panelp);
783 }
784
785 release_region(brdp->ioaddr1, brdp->iosize1);
786 if (brdp->iosize2 > 0)
787 release_region(brdp->ioaddr2, brdp->iosize2);
788
789 kfree(brdp);
Jiri Slaby615e4a72006-12-08 02:38:38 -0800790 stl_brds[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792}
793
794module_init(stallion_module_init);
795module_exit(stallion_module_exit);
796
797/*****************************************************************************/
798
799/*
800 * Check for any arguments passed in on the module load command line.
801 */
802
803static void stl_argbrds(void)
804{
805 stlconf_t conf;
806 stlbrd_t *brdp;
807 int i;
808
Jiri Slabya0564e12006-12-08 02:38:37 -0800809 pr_debug("stl_argbrds()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
811 for (i = stl_nrbrds; (i < stl_nargs); i++) {
812 memset(&conf, 0, sizeof(conf));
813 if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
814 continue;
Jiri Slaby615e4a72006-12-08 02:38:38 -0800815 if ((brdp = stl_allocbrd()) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 continue;
817 stl_nrbrds = i + 1;
818 brdp->brdnr = i;
819 brdp->brdtype = conf.brdtype;
820 brdp->ioaddr1 = conf.ioaddr1;
821 brdp->ioaddr2 = conf.ioaddr2;
822 brdp->irq = conf.irq;
823 brdp->irqtype = conf.irqtype;
824 stl_brdinit(brdp);
825 }
826}
827
828/*****************************************************************************/
829
830/*
831 * Convert an ascii string number into an unsigned long.
832 */
833
834static unsigned long stl_atol(char *str)
835{
836 unsigned long val;
837 int base, c;
838 char *sp;
839
840 val = 0;
841 sp = str;
842 if ((*sp == '0') && (*(sp+1) == 'x')) {
843 base = 16;
844 sp += 2;
845 } else if (*sp == '0') {
846 base = 8;
847 sp++;
848 } else {
849 base = 10;
850 }
851
852 for (; (*sp != 0); sp++) {
853 c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
854 if ((c < 0) || (c >= base)) {
855 printk("STALLION: invalid argument %s\n", str);
856 val = 0;
857 break;
858 }
859 val = (val * base) + c;
860 }
Jesper Juhl014c2542006-01-15 02:37:08 +0100861 return val;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862}
863
864/*****************************************************************************/
865
866/*
867 * Parse the supplied argument string, into the board conf struct.
868 */
869
870static int stl_parsebrd(stlconf_t *confp, char **argp)
871{
872 char *sp;
Tobias Klauserfe971072006-01-09 20:54:02 -0800873 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Jiri Slabya0564e12006-12-08 02:38:37 -0800875 pr_debug("stl_parsebrd(confp=%p,argp=%p)\n", confp, argp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
Jiri Slaby615e4a72006-12-08 02:38:38 -0800877 if ((argp[0] == NULL) || (*argp[0] == 0))
Jesper Juhl014c2542006-01-15 02:37:08 +0100878 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
880 for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
881 *sp = TOLOWER(*sp);
882
Tobias Klauserfe971072006-01-09 20:54:02 -0800883 for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 if (strcmp(stl_brdstr[i].name, argp[0]) == 0)
885 break;
886 }
Tobias Klauserfe971072006-01-09 20:54:02 -0800887 if (i == ARRAY_SIZE(stl_brdstr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 printk("STALLION: unknown board name, %s?\n", argp[0]);
Tobias Klauserfe971072006-01-09 20:54:02 -0800889 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 }
891
892 confp->brdtype = stl_brdstr[i].type;
893
894 i = 1;
Jiri Slaby615e4a72006-12-08 02:38:38 -0800895 if ((argp[i] != NULL) && (*argp[i] != 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 confp->ioaddr1 = stl_atol(argp[i]);
897 i++;
898 if (confp->brdtype == BRD_ECH) {
Jiri Slaby615e4a72006-12-08 02:38:38 -0800899 if ((argp[i] != NULL) && (*argp[i] != 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 confp->ioaddr2 = stl_atol(argp[i]);
901 i++;
902 }
Jiri Slaby615e4a72006-12-08 02:38:38 -0800903 if ((argp[i] != NULL) && (*argp[i] != 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 confp->irq = stl_atol(argp[i]);
Jesper Juhl014c2542006-01-15 02:37:08 +0100905 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906}
907
908/*****************************************************************************/
909
910/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 * Allocate a new board structure. Fill out the basic info in it.
912 */
913
914static stlbrd_t *stl_allocbrd(void)
915{
916 stlbrd_t *brdp;
917
Tobias Klauserb0b4ed72006-03-31 02:30:56 -0800918 brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL);
919 if (!brdp) {
Alan Coxb65b5b52006-06-27 02:54:05 -0700920 printk("STALLION: failed to allocate memory (size=%Zd)\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 sizeof(stlbrd_t));
Tobias Klauserb0b4ed72006-03-31 02:30:56 -0800922 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 }
924
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 brdp->magic = STL_BOARDMAGIC;
Jesper Juhl014c2542006-01-15 02:37:08 +0100926 return brdp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927}
928
929/*****************************************************************************/
930
931static int stl_open(struct tty_struct *tty, struct file *filp)
932{
933 stlport_t *portp;
934 stlbrd_t *brdp;
935 unsigned int minordev;
936 int brdnr, panelnr, portnr, rc;
937
Jiri Slabya0564e12006-12-08 02:38:37 -0800938 pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939
940 minordev = tty->index;
941 brdnr = MINOR2BRD(minordev);
942 if (brdnr >= stl_nrbrds)
Jesper Juhl014c2542006-01-15 02:37:08 +0100943 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 brdp = stl_brds[brdnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -0800945 if (brdp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +0100946 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 minordev = MINOR2PORT(minordev);
948 for (portnr = -1, panelnr = 0; (panelnr < STL_MAXPANELS); panelnr++) {
Jiri Slaby615e4a72006-12-08 02:38:38 -0800949 if (brdp->panels[panelnr] == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 break;
951 if (minordev < brdp->panels[panelnr]->nrports) {
952 portnr = minordev;
953 break;
954 }
955 minordev -= brdp->panels[panelnr]->nrports;
956 }
957 if (portnr < 0)
Jesper Juhl014c2542006-01-15 02:37:08 +0100958 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
960 portp = brdp->panels[panelnr]->ports[portnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -0800961 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +0100962 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963
964/*
965 * On the first open of the device setup the port hardware, and
966 * initialize the per port data structure.
967 */
968 portp->tty = tty;
969 tty->driver_data = portp;
970 portp->refcount++;
971
972 if ((portp->flags & ASYNC_INITIALIZED) == 0) {
Tobias Klauserb0b4ed72006-03-31 02:30:56 -0800973 if (!portp->tx.buf) {
974 portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
975 if (!portp->tx.buf)
Jesper Juhl014c2542006-01-15 02:37:08 +0100976 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 portp->tx.head = portp->tx.buf;
978 portp->tx.tail = portp->tx.buf;
979 }
980 stl_setport(portp, tty->termios);
981 portp->sigs = stl_getsignals(portp);
982 stl_setsignals(portp, 1, 1);
983 stl_enablerxtx(portp, 1, 1);
984 stl_startrxtx(portp, 1, 0);
985 clear_bit(TTY_IO_ERROR, &tty->flags);
986 portp->flags |= ASYNC_INITIALIZED;
987 }
988
989/*
990 * Check if this port is in the middle of closing. If so then wait
991 * until it is closed then return error status, based on flag settings.
992 * The sleep here does not need interrupt protection since the wakeup
993 * for it is done with the same context.
994 */
995 if (portp->flags & ASYNC_CLOSING) {
996 interruptible_sleep_on(&portp->close_wait);
997 if (portp->flags & ASYNC_HUP_NOTIFY)
Jesper Juhl014c2542006-01-15 02:37:08 +0100998 return -EAGAIN;
999 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 }
1001
1002/*
1003 * Based on type of open being done check if it can overlap with any
1004 * previous opens still in effect. If we are a normal serial device
1005 * then also we might have to wait for carrier.
1006 */
1007 if (!(filp->f_flags & O_NONBLOCK)) {
1008 if ((rc = stl_waitcarrier(portp, filp)) != 0)
Jesper Juhl014c2542006-01-15 02:37:08 +01001009 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 }
1011 portp->flags |= ASYNC_NORMAL_ACTIVE;
1012
Jesper Juhl014c2542006-01-15 02:37:08 +01001013 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014}
1015
1016/*****************************************************************************/
1017
1018/*
1019 * Possibly need to wait for carrier (DCD signal) to come high. Say
1020 * maybe because if we are clocal then we don't need to wait...
1021 */
1022
1023static int stl_waitcarrier(stlport_t *portp, struct file *filp)
1024{
1025 unsigned long flags;
1026 int rc, doclocal;
1027
Jiri Slabya0564e12006-12-08 02:38:37 -08001028 pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
1030 rc = 0;
1031 doclocal = 0;
1032
Alan Coxb65b5b52006-06-27 02:54:05 -07001033 spin_lock_irqsave(&stallion_lock, flags);
1034
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 if (portp->tty->termios->c_cflag & CLOCAL)
1036 doclocal++;
1037
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 portp->openwaitcnt++;
1039 if (! tty_hung_up_p(filp))
1040 portp->refcount--;
1041
1042 for (;;) {
Alan Coxb65b5b52006-06-27 02:54:05 -07001043 /* Takes brd_lock internally */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 stl_setsignals(portp, 1, 1);
1045 if (tty_hung_up_p(filp) ||
1046 ((portp->flags & ASYNC_INITIALIZED) == 0)) {
1047 if (portp->flags & ASYNC_HUP_NOTIFY)
1048 rc = -EBUSY;
1049 else
1050 rc = -ERESTARTSYS;
1051 break;
1052 }
1053 if (((portp->flags & ASYNC_CLOSING) == 0) &&
1054 (doclocal || (portp->sigs & TIOCM_CD))) {
1055 break;
1056 }
1057 if (signal_pending(current)) {
1058 rc = -ERESTARTSYS;
1059 break;
1060 }
Alan Coxb65b5b52006-06-27 02:54:05 -07001061 /* FIXME */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 interruptible_sleep_on(&portp->open_wait);
1063 }
1064
1065 if (! tty_hung_up_p(filp))
1066 portp->refcount++;
1067 portp->openwaitcnt--;
Alan Coxb65b5b52006-06-27 02:54:05 -07001068 spin_unlock_irqrestore(&stallion_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069
Jesper Juhl014c2542006-01-15 02:37:08 +01001070 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071}
1072
1073/*****************************************************************************/
1074
1075static void stl_close(struct tty_struct *tty, struct file *filp)
1076{
1077 stlport_t *portp;
1078 unsigned long flags;
1079
Jiri Slabya0564e12006-12-08 02:38:37 -08001080 pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
1082 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001083 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 return;
1085
Alan Coxb65b5b52006-06-27 02:54:05 -07001086 spin_lock_irqsave(&stallion_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 if (tty_hung_up_p(filp)) {
Alan Coxb65b5b52006-06-27 02:54:05 -07001088 spin_unlock_irqrestore(&stallion_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 return;
1090 }
1091 if ((tty->count == 1) && (portp->refcount != 1))
1092 portp->refcount = 1;
1093 if (portp->refcount-- > 1) {
Alan Coxb65b5b52006-06-27 02:54:05 -07001094 spin_unlock_irqrestore(&stallion_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 return;
1096 }
1097
1098 portp->refcount = 0;
1099 portp->flags |= ASYNC_CLOSING;
1100
1101/*
1102 * May want to wait for any data to drain before closing. The BUSY
1103 * flag keeps track of whether we are still sending or not - it is
1104 * very accurate for the cd1400, not quite so for the sc26198.
1105 * (The sc26198 has no "end-of-data" interrupt only empty FIFO)
1106 */
1107 tty->closing = 1;
Alan Coxb65b5b52006-06-27 02:54:05 -07001108
1109 spin_unlock_irqrestore(&stallion_lock, flags);
1110
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1112 tty_wait_until_sent(tty, portp->closing_wait);
1113 stl_waituntilsent(tty, (HZ / 2));
1114
Alan Coxb65b5b52006-06-27 02:54:05 -07001115
1116 spin_lock_irqsave(&stallion_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 portp->flags &= ~ASYNC_INITIALIZED;
Alan Coxb65b5b52006-06-27 02:54:05 -07001118 spin_unlock_irqrestore(&stallion_lock, flags);
1119
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 stl_disableintrs(portp);
1121 if (tty->termios->c_cflag & HUPCL)
1122 stl_setsignals(portp, 0, 0);
1123 stl_enablerxtx(portp, 0, 0);
1124 stl_flushbuffer(tty);
1125 portp->istate = 0;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001126 if (portp->tx.buf != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 kfree(portp->tx.buf);
Jiri Slaby615e4a72006-12-08 02:38:38 -08001128 portp->tx.buf = NULL;
1129 portp->tx.head = NULL;
1130 portp->tx.tail = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 }
1132 set_bit(TTY_IO_ERROR, &tty->flags);
1133 tty_ldisc_flush(tty);
1134
1135 tty->closing = 0;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001136 portp->tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
1138 if (portp->openwaitcnt) {
1139 if (portp->close_delay)
1140 msleep_interruptible(jiffies_to_msecs(portp->close_delay));
1141 wake_up_interruptible(&portp->open_wait);
1142 }
1143
1144 portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1145 wake_up_interruptible(&portp->close_wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146}
1147
1148/*****************************************************************************/
1149
1150/*
1151 * Write routine. Take data and stuff it in to the TX ring queue.
1152 * If transmit interrupts are not running then start them.
1153 */
1154
1155static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count)
1156{
1157 stlport_t *portp;
1158 unsigned int len, stlen;
1159 unsigned char *chbuf;
1160 char *head, *tail;
1161
Jiri Slabya0564e12006-12-08 02:38:37 -08001162 pr_debug("stl_write(tty=%p,buf=%p,count=%d)\n", tty, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001165 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001166 return 0;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001167 if (portp->tx.buf == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001168 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169
1170/*
1171 * If copying direct from user space we must cater for page faults,
1172 * causing us to "sleep" here for a while. To handle this copy in all
1173 * the data we need now, into a local buffer. Then when we got it all
1174 * copy it into the TX buffer.
1175 */
1176 chbuf = (unsigned char *) buf;
1177
1178 head = portp->tx.head;
1179 tail = portp->tx.tail;
1180 if (head >= tail) {
1181 len = STL_TXBUFSIZE - (head - tail) - 1;
1182 stlen = STL_TXBUFSIZE - (head - portp->tx.buf);
1183 } else {
1184 len = tail - head - 1;
1185 stlen = len;
1186 }
1187
1188 len = MIN(len, count);
1189 count = 0;
1190 while (len > 0) {
1191 stlen = MIN(len, stlen);
1192 memcpy(head, chbuf, stlen);
1193 len -= stlen;
1194 chbuf += stlen;
1195 count += stlen;
1196 head += stlen;
1197 if (head >= (portp->tx.buf + STL_TXBUFSIZE)) {
1198 head = portp->tx.buf;
1199 stlen = tail - head;
1200 }
1201 }
1202 portp->tx.head = head;
1203
1204 clear_bit(ASYI_TXLOW, &portp->istate);
1205 stl_startrxtx(portp, -1, 1);
1206
Jesper Juhl014c2542006-01-15 02:37:08 +01001207 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208}
1209
1210/*****************************************************************************/
1211
1212static void stl_putchar(struct tty_struct *tty, unsigned char ch)
1213{
1214 stlport_t *portp;
1215 unsigned int len;
1216 char *head, *tail;
1217
Jiri Slabya0564e12006-12-08 02:38:37 -08001218 pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
Jiri Slaby615e4a72006-12-08 02:38:38 -08001220 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 return;
1222 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001223 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 return;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001225 if (portp->tx.buf == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 return;
1227
1228 head = portp->tx.head;
1229 tail = portp->tx.tail;
1230
1231 len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail)) : (tail - head);
1232 len--;
1233
1234 if (len > 0) {
1235 *head++ = ch;
1236 if (head >= (portp->tx.buf + STL_TXBUFSIZE))
1237 head = portp->tx.buf;
1238 }
1239 portp->tx.head = head;
1240}
1241
1242/*****************************************************************************/
1243
1244/*
1245 * If there are any characters in the buffer then make sure that TX
1246 * interrupts are on and get'em out. Normally used after the putchar
1247 * routine has been called.
1248 */
1249
1250static void stl_flushchars(struct tty_struct *tty)
1251{
1252 stlport_t *portp;
1253
Jiri Slabya0564e12006-12-08 02:38:37 -08001254 pr_debug("stl_flushchars(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
Jiri Slaby615e4a72006-12-08 02:38:38 -08001256 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257 return;
1258 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001259 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 return;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001261 if (portp->tx.buf == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262 return;
1263
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 stl_startrxtx(portp, -1, 1);
1265}
1266
1267/*****************************************************************************/
1268
1269static int stl_writeroom(struct tty_struct *tty)
1270{
1271 stlport_t *portp;
1272 char *head, *tail;
1273
Jiri Slabya0564e12006-12-08 02:38:37 -08001274 pr_debug("stl_writeroom(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275
Jiri Slaby615e4a72006-12-08 02:38:38 -08001276 if (tty == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001277 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001279 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001280 return 0;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001281 if (portp->tx.buf == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001282 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283
1284 head = portp->tx.head;
1285 tail = portp->tx.tail;
Jesper Juhl014c2542006-01-15 02:37:08 +01001286 return ((head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287}
1288
1289/*****************************************************************************/
1290
1291/*
1292 * Return number of chars in the TX buffer. Normally we would just
1293 * calculate the number of chars in the buffer and return that, but if
1294 * the buffer is empty and TX interrupts are still on then we return
1295 * that the buffer still has 1 char in it. This way whoever called us
1296 * will not think that ALL chars have drained - since the UART still
1297 * must have some chars in it (we are busy after all).
1298 */
1299
1300static int stl_charsinbuffer(struct tty_struct *tty)
1301{
1302 stlport_t *portp;
1303 unsigned int size;
1304 char *head, *tail;
1305
Jiri Slabya0564e12006-12-08 02:38:37 -08001306 pr_debug("stl_charsinbuffer(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
Jiri Slaby615e4a72006-12-08 02:38:38 -08001308 if (tty == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001309 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001311 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001312 return 0;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001313 if (portp->tx.buf == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001314 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
1316 head = portp->tx.head;
1317 tail = portp->tx.tail;
1318 size = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
1319 if ((size == 0) && test_bit(ASYI_TXBUSY, &portp->istate))
1320 size = 1;
Jesper Juhl014c2542006-01-15 02:37:08 +01001321 return size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322}
1323
1324/*****************************************************************************/
1325
1326/*
1327 * Generate the serial struct info.
1328 */
1329
1330static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp)
1331{
1332 struct serial_struct sio;
1333 stlbrd_t *brdp;
1334
Jiri Slabya0564e12006-12-08 02:38:37 -08001335 pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336
1337 memset(&sio, 0, sizeof(struct serial_struct));
1338 sio.line = portp->portnr;
1339 sio.port = portp->ioaddr;
1340 sio.flags = portp->flags;
1341 sio.baud_base = portp->baud_base;
1342 sio.close_delay = portp->close_delay;
1343 sio.closing_wait = portp->closing_wait;
1344 sio.custom_divisor = portp->custom_divisor;
1345 sio.hub6 = 0;
1346 if (portp->uartp == &stl_cd1400uart) {
1347 sio.type = PORT_CIRRUS;
1348 sio.xmit_fifo_size = CD1400_TXFIFOSIZE;
1349 } else {
1350 sio.type = PORT_UNKNOWN;
1351 sio.xmit_fifo_size = SC26198_TXFIFOSIZE;
1352 }
1353
1354 brdp = stl_brds[portp->brdnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08001355 if (brdp != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 sio.irq = brdp->irq;
1357
1358 return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0;
1359}
1360
1361/*****************************************************************************/
1362
1363/*
1364 * Set port according to the serial struct info.
1365 * At this point we do not do any auto-configure stuff, so we will
1366 * just quietly ignore any requests to change irq, etc.
1367 */
1368
1369static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp)
1370{
1371 struct serial_struct sio;
1372
Jiri Slabya0564e12006-12-08 02:38:37 -08001373 pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
1375 if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
1376 return -EFAULT;
1377 if (!capable(CAP_SYS_ADMIN)) {
1378 if ((sio.baud_base != portp->baud_base) ||
1379 (sio.close_delay != portp->close_delay) ||
1380 ((sio.flags & ~ASYNC_USR_MASK) !=
1381 (portp->flags & ~ASYNC_USR_MASK)))
Jesper Juhl014c2542006-01-15 02:37:08 +01001382 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 }
1384
1385 portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
1386 (sio.flags & ASYNC_USR_MASK);
1387 portp->baud_base = sio.baud_base;
1388 portp->close_delay = sio.close_delay;
1389 portp->closing_wait = sio.closing_wait;
1390 portp->custom_divisor = sio.custom_divisor;
1391 stl_setport(portp, portp->tty->termios);
Jesper Juhl014c2542006-01-15 02:37:08 +01001392 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393}
1394
1395/*****************************************************************************/
1396
1397static int stl_tiocmget(struct tty_struct *tty, struct file *file)
1398{
1399 stlport_t *portp;
1400
Jiri Slaby615e4a72006-12-08 02:38:38 -08001401 if (tty == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001402 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001404 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001405 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 if (tty->flags & (1 << TTY_IO_ERROR))
Jesper Juhl014c2542006-01-15 02:37:08 +01001407 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
1409 return stl_getsignals(portp);
1410}
1411
1412static int stl_tiocmset(struct tty_struct *tty, struct file *file,
1413 unsigned int set, unsigned int clear)
1414{
1415 stlport_t *portp;
1416 int rts = -1, dtr = -1;
1417
Jiri Slaby615e4a72006-12-08 02:38:38 -08001418 if (tty == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001419 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001421 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001422 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 if (tty->flags & (1 << TTY_IO_ERROR))
Jesper Juhl014c2542006-01-15 02:37:08 +01001424 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
1426 if (set & TIOCM_RTS)
1427 rts = 1;
1428 if (set & TIOCM_DTR)
1429 dtr = 1;
1430 if (clear & TIOCM_RTS)
1431 rts = 0;
1432 if (clear & TIOCM_DTR)
1433 dtr = 0;
1434
1435 stl_setsignals(portp, dtr, rts);
1436 return 0;
1437}
1438
1439static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1440{
1441 stlport_t *portp;
1442 unsigned int ival;
1443 int rc;
1444 void __user *argp = (void __user *)arg;
1445
Jiri Slabya0564e12006-12-08 02:38:37 -08001446 pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd,
1447 arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448
Jiri Slaby615e4a72006-12-08 02:38:38 -08001449 if (tty == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001450 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001452 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01001453 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
1455 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1456 (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
1457 if (tty->flags & (1 << TTY_IO_ERROR))
Jesper Juhl014c2542006-01-15 02:37:08 +01001458 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 }
1460
1461 rc = 0;
1462
1463 switch (cmd) {
1464 case TIOCGSOFTCAR:
1465 rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
1466 (unsigned __user *) argp);
1467 break;
1468 case TIOCSSOFTCAR:
1469 if (get_user(ival, (unsigned int __user *) arg))
1470 return -EFAULT;
1471 tty->termios->c_cflag =
1472 (tty->termios->c_cflag & ~CLOCAL) |
1473 (ival ? CLOCAL : 0);
1474 break;
1475 case TIOCGSERIAL:
1476 rc = stl_getserial(portp, argp);
1477 break;
1478 case TIOCSSERIAL:
1479 rc = stl_setserial(portp, argp);
1480 break;
1481 case COM_GETPORTSTATS:
1482 rc = stl_getportstats(portp, argp);
1483 break;
1484 case COM_CLRPORTSTATS:
1485 rc = stl_clrportstats(portp, argp);
1486 break;
1487 case TIOCSERCONFIG:
1488 case TIOCSERGWILD:
1489 case TIOCSERSWILD:
1490 case TIOCSERGETLSR:
1491 case TIOCSERGSTRUCT:
1492 case TIOCSERGETMULTI:
1493 case TIOCSERSETMULTI:
1494 default:
1495 rc = -ENOIOCTLCMD;
1496 break;
1497 }
1498
Jesper Juhl014c2542006-01-15 02:37:08 +01001499 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500}
1501
1502/*****************************************************************************/
1503
1504static void stl_settermios(struct tty_struct *tty, struct termios *old)
1505{
1506 stlport_t *portp;
1507 struct termios *tiosp;
1508
Jiri Slabya0564e12006-12-08 02:38:37 -08001509 pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
Jiri Slaby615e4a72006-12-08 02:38:38 -08001511 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 return;
1513 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001514 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 return;
1516
1517 tiosp = tty->termios;
1518 if ((tiosp->c_cflag == old->c_cflag) &&
1519 (tiosp->c_iflag == old->c_iflag))
1520 return;
1521
1522 stl_setport(portp, tiosp);
1523 stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0),
1524 -1);
1525 if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) {
1526 tty->hw_stopped = 0;
1527 stl_start(tty);
1528 }
1529 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
1530 wake_up_interruptible(&portp->open_wait);
1531}
1532
1533/*****************************************************************************/
1534
1535/*
1536 * Attempt to flow control who ever is sending us data. Based on termios
1537 * settings use software or/and hardware flow control.
1538 */
1539
1540static void stl_throttle(struct tty_struct *tty)
1541{
1542 stlport_t *portp;
1543
Jiri Slabya0564e12006-12-08 02:38:37 -08001544 pr_debug("stl_throttle(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545
Jiri Slaby615e4a72006-12-08 02:38:38 -08001546 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 return;
1548 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001549 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 return;
1551 stl_flowctrl(portp, 0);
1552}
1553
1554/*****************************************************************************/
1555
1556/*
1557 * Unflow control the device sending us data...
1558 */
1559
1560static void stl_unthrottle(struct tty_struct *tty)
1561{
1562 stlport_t *portp;
1563
Jiri Slabya0564e12006-12-08 02:38:37 -08001564 pr_debug("stl_unthrottle(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565
Jiri Slaby615e4a72006-12-08 02:38:38 -08001566 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 return;
1568 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001569 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 return;
1571 stl_flowctrl(portp, 1);
1572}
1573
1574/*****************************************************************************/
1575
1576/*
1577 * Stop the transmitter. Basically to do this we will just turn TX
1578 * interrupts off.
1579 */
1580
1581static void stl_stop(struct tty_struct *tty)
1582{
1583 stlport_t *portp;
1584
Jiri Slabya0564e12006-12-08 02:38:37 -08001585 pr_debug("stl_stop(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
Jiri Slaby615e4a72006-12-08 02:38:38 -08001587 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 return;
1589 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001590 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 return;
1592 stl_startrxtx(portp, -1, 0);
1593}
1594
1595/*****************************************************************************/
1596
1597/*
1598 * Start the transmitter again. Just turn TX interrupts back on.
1599 */
1600
1601static void stl_start(struct tty_struct *tty)
1602{
1603 stlport_t *portp;
1604
Jiri Slabya0564e12006-12-08 02:38:37 -08001605 pr_debug("stl_start(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606
Jiri Slaby615e4a72006-12-08 02:38:38 -08001607 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 return;
1609 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001610 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 return;
1612 stl_startrxtx(portp, -1, 1);
1613}
1614
1615/*****************************************************************************/
1616
1617/*
1618 * Hangup this port. This is pretty much like closing the port, only
1619 * a little more brutal. No waiting for data to drain. Shutdown the
1620 * port and maybe drop signals.
1621 */
1622
1623static void stl_hangup(struct tty_struct *tty)
1624{
1625 stlport_t *portp;
1626
Jiri Slabya0564e12006-12-08 02:38:37 -08001627 pr_debug("stl_hangup(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628
Jiri Slaby615e4a72006-12-08 02:38:38 -08001629 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 return;
1631 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001632 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 return;
1634
1635 portp->flags &= ~ASYNC_INITIALIZED;
1636 stl_disableintrs(portp);
1637 if (tty->termios->c_cflag & HUPCL)
1638 stl_setsignals(portp, 0, 0);
1639 stl_enablerxtx(portp, 0, 0);
1640 stl_flushbuffer(tty);
1641 portp->istate = 0;
1642 set_bit(TTY_IO_ERROR, &tty->flags);
Jiri Slaby615e4a72006-12-08 02:38:38 -08001643 if (portp->tx.buf != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 kfree(portp->tx.buf);
Jiri Slaby615e4a72006-12-08 02:38:38 -08001645 portp->tx.buf = NULL;
1646 portp->tx.head = NULL;
1647 portp->tx.tail = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 }
Jiri Slaby615e4a72006-12-08 02:38:38 -08001649 portp->tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 portp->flags &= ~ASYNC_NORMAL_ACTIVE;
1651 portp->refcount = 0;
1652 wake_up_interruptible(&portp->open_wait);
1653}
1654
1655/*****************************************************************************/
1656
1657static void stl_flushbuffer(struct tty_struct *tty)
1658{
1659 stlport_t *portp;
1660
Jiri Slabya0564e12006-12-08 02:38:37 -08001661 pr_debug("stl_flushbuffer(tty=%p)\n", tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
Jiri Slaby615e4a72006-12-08 02:38:38 -08001663 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 return;
1665 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001666 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 return;
1668
1669 stl_flush(portp);
1670 tty_wakeup(tty);
1671}
1672
1673/*****************************************************************************/
1674
1675static void stl_breakctl(struct tty_struct *tty, int state)
1676{
1677 stlport_t *portp;
1678
Jiri Slabya0564e12006-12-08 02:38:37 -08001679 pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
Jiri Slaby615e4a72006-12-08 02:38:38 -08001681 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 return;
1683 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001684 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 return;
1686
1687 stl_sendbreak(portp, ((state == -1) ? 1 : 2));
1688}
1689
1690/*****************************************************************************/
1691
1692static void stl_waituntilsent(struct tty_struct *tty, int timeout)
1693{
1694 stlport_t *portp;
1695 unsigned long tend;
1696
Jiri Slabya0564e12006-12-08 02:38:37 -08001697 pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
Jiri Slaby615e4a72006-12-08 02:38:38 -08001699 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 return;
1701 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001702 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 return;
1704
1705 if (timeout == 0)
1706 timeout = HZ;
1707 tend = jiffies + timeout;
1708
1709 while (stl_datastate(portp)) {
1710 if (signal_pending(current))
1711 break;
1712 msleep_interruptible(20);
1713 if (time_after_eq(jiffies, tend))
1714 break;
1715 }
1716}
1717
1718/*****************************************************************************/
1719
1720static void stl_sendxchar(struct tty_struct *tty, char ch)
1721{
1722 stlport_t *portp;
1723
Jiri Slabya0564e12006-12-08 02:38:37 -08001724 pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
Jiri Slaby615e4a72006-12-08 02:38:38 -08001726 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 return;
1728 portp = tty->driver_data;
Jiri Slaby615e4a72006-12-08 02:38:38 -08001729 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 return;
1731
1732 if (ch == STOP_CHAR(tty))
1733 stl_sendflow(portp, 0);
1734 else if (ch == START_CHAR(tty))
1735 stl_sendflow(portp, 1);
1736 else
1737 stl_putchar(tty, ch);
1738}
1739
1740/*****************************************************************************/
1741
1742#define MAXLINE 80
1743
1744/*
1745 * Format info for a specified port. The line is deliberately limited
1746 * to 80 characters. (If it is too long it will be truncated, if too
1747 * short then padded with spaces).
1748 */
1749
1750static int stl_portinfo(stlport_t *portp, int portnr, char *pos)
1751{
1752 char *sp;
1753 int sigs, cnt;
1754
1755 sp = pos;
1756 sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
1757 portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
1758 (int) portp->stats.txtotal, (int) portp->stats.rxtotal);
1759
1760 if (portp->stats.rxframing)
1761 sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
1762 if (portp->stats.rxparity)
1763 sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
1764 if (portp->stats.rxbreaks)
1765 sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
1766 if (portp->stats.rxoverrun)
1767 sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
1768
1769 sigs = stl_getsignals(portp);
1770 cnt = sprintf(sp, "%s%s%s%s%s ",
1771 (sigs & TIOCM_RTS) ? "|RTS" : "",
1772 (sigs & TIOCM_CTS) ? "|CTS" : "",
1773 (sigs & TIOCM_DTR) ? "|DTR" : "",
1774 (sigs & TIOCM_CD) ? "|DCD" : "",
1775 (sigs & TIOCM_DSR) ? "|DSR" : "");
1776 *sp = ' ';
1777 sp += cnt;
1778
1779 for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
1780 *sp++ = ' ';
1781 if (cnt >= MAXLINE)
1782 pos[(MAXLINE - 2)] = '+';
1783 pos[(MAXLINE - 1)] = '\n';
1784
Jesper Juhl014c2542006-01-15 02:37:08 +01001785 return MAXLINE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786}
1787
1788/*****************************************************************************/
1789
1790/*
1791 * Port info, read from the /proc file system.
1792 */
1793
1794static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
1795{
1796 stlbrd_t *brdp;
1797 stlpanel_t *panelp;
1798 stlport_t *portp;
1799 int brdnr, panelnr, portnr, totalport;
1800 int curoff, maxoff;
1801 char *pos;
1802
Jiri Slabya0564e12006-12-08 02:38:37 -08001803 pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p,"
1804 "data=%p\n", page, start, off, count, eof, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805
1806 pos = page;
1807 totalport = 0;
1808 curoff = 0;
1809
1810 if (off == 0) {
1811 pos += sprintf(pos, "%s: version %s", stl_drvtitle,
1812 stl_drvversion);
1813 while (pos < (page + MAXLINE - 1))
1814 *pos++ = ' ';
1815 *pos++ = '\n';
1816 }
1817 curoff = MAXLINE;
1818
1819/*
1820 * We scan through for each board, panel and port. The offset is
1821 * calculated on the fly, and irrelevant ports are skipped.
1822 */
1823 for (brdnr = 0; (brdnr < stl_nrbrds); brdnr++) {
1824 brdp = stl_brds[brdnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08001825 if (brdp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 continue;
1827 if (brdp->state == 0)
1828 continue;
1829
1830 maxoff = curoff + (brdp->nrports * MAXLINE);
1831 if (off >= maxoff) {
1832 curoff = maxoff;
1833 continue;
1834 }
1835
1836 totalport = brdnr * STL_MAXPORTS;
1837 for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
1838 panelp = brdp->panels[panelnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08001839 if (panelp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 continue;
1841
1842 maxoff = curoff + (panelp->nrports * MAXLINE);
1843 if (off >= maxoff) {
1844 curoff = maxoff;
1845 totalport += panelp->nrports;
1846 continue;
1847 }
1848
1849 for (portnr = 0; (portnr < panelp->nrports); portnr++,
1850 totalport++) {
1851 portp = panelp->ports[portnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08001852 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 continue;
1854 if (off >= (curoff += MAXLINE))
1855 continue;
1856 if ((pos - page + MAXLINE) > count)
1857 goto stl_readdone;
1858 pos += stl_portinfo(portp, totalport, pos);
1859 }
1860 }
1861 }
1862
1863 *eof = 1;
1864
1865stl_readdone:
1866 *start = page;
Jesper Juhl014c2542006-01-15 02:37:08 +01001867 return (pos - page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868}
1869
1870/*****************************************************************************/
1871
1872/*
1873 * All board interrupts are vectored through here first. This code then
1874 * calls off to the approrpriate board interrupt handlers.
1875 */
1876
David Howells7d12e782006-10-05 14:55:46 +01001877static irqreturn_t stl_intr(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878{
Jiri Slaby615e4a72006-12-08 02:38:38 -08001879 stlbrd_t *brdp = dev_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880
Jiri Slabya0564e12006-12-08 02:38:37 -08001881 pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
1883 return IRQ_RETVAL((* brdp->isr)(brdp));
1884}
1885
1886/*****************************************************************************/
1887
1888/*
1889 * Interrupt service routine for EasyIO board types.
1890 */
1891
1892static int stl_eiointr(stlbrd_t *brdp)
1893{
1894 stlpanel_t *panelp;
1895 unsigned int iobase;
1896 int handled = 0;
1897
Alan Coxb65b5b52006-06-27 02:54:05 -07001898 spin_lock(&brd_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 panelp = brdp->panels[0];
1900 iobase = panelp->iobase;
1901 while (inb(brdp->iostatus) & EIO_INTRPEND) {
1902 handled = 1;
1903 (* panelp->isr)(panelp, iobase);
1904 }
Alan Coxb65b5b52006-06-27 02:54:05 -07001905 spin_unlock(&brd_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 return handled;
1907}
1908
1909/*****************************************************************************/
1910
1911/*
1912 * Interrupt service routine for ECH-AT board types.
1913 */
1914
1915static int stl_echatintr(stlbrd_t *brdp)
1916{
1917 stlpanel_t *panelp;
1918 unsigned int ioaddr;
1919 int bnknr;
1920 int handled = 0;
1921
1922 outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
1923
1924 while (inb(brdp->iostatus) & ECH_INTRPEND) {
1925 handled = 1;
1926 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
1927 ioaddr = brdp->bnkstataddr[bnknr];
1928 if (inb(ioaddr) & ECH_PNLINTRPEND) {
1929 panelp = brdp->bnk2panel[bnknr];
1930 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
1931 }
1932 }
1933 }
1934
1935 outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
1936
1937 return handled;
1938}
1939
1940/*****************************************************************************/
1941
1942/*
1943 * Interrupt service routine for ECH-MCA board types.
1944 */
1945
1946static int stl_echmcaintr(stlbrd_t *brdp)
1947{
1948 stlpanel_t *panelp;
1949 unsigned int ioaddr;
1950 int bnknr;
1951 int handled = 0;
1952
1953 while (inb(brdp->iostatus) & ECH_INTRPEND) {
1954 handled = 1;
1955 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
1956 ioaddr = brdp->bnkstataddr[bnknr];
1957 if (inb(ioaddr) & ECH_PNLINTRPEND) {
1958 panelp = brdp->bnk2panel[bnknr];
1959 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
1960 }
1961 }
1962 }
1963 return handled;
1964}
1965
1966/*****************************************************************************/
1967
1968/*
1969 * Interrupt service routine for ECH-PCI board types.
1970 */
1971
1972static int stl_echpciintr(stlbrd_t *brdp)
1973{
1974 stlpanel_t *panelp;
1975 unsigned int ioaddr;
1976 int bnknr, recheck;
1977 int handled = 0;
1978
1979 while (1) {
1980 recheck = 0;
1981 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
1982 outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl);
1983 ioaddr = brdp->bnkstataddr[bnknr];
1984 if (inb(ioaddr) & ECH_PNLINTRPEND) {
1985 panelp = brdp->bnk2panel[bnknr];
1986 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
1987 recheck++;
1988 handled = 1;
1989 }
1990 }
1991 if (! recheck)
1992 break;
1993 }
1994 return handled;
1995}
1996
1997/*****************************************************************************/
1998
1999/*
2000 * Interrupt service routine for ECH-8/64-PCI board types.
2001 */
2002
2003static int stl_echpci64intr(stlbrd_t *brdp)
2004{
2005 stlpanel_t *panelp;
2006 unsigned int ioaddr;
2007 int bnknr;
2008 int handled = 0;
2009
2010 while (inb(brdp->ioctrl) & 0x1) {
2011 handled = 1;
2012 for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
2013 ioaddr = brdp->bnkstataddr[bnknr];
2014 if (inb(ioaddr) & ECH_PNLINTRPEND) {
2015 panelp = brdp->bnk2panel[bnknr];
2016 (* panelp->isr)(panelp, (ioaddr & 0xfffc));
2017 }
2018 }
2019 }
2020
2021 return handled;
2022}
2023
2024/*****************************************************************************/
2025
2026/*
2027 * Service an off-level request for some channel.
2028 */
Al Viro3e577a82006-12-06 18:41:45 +00002029static void stl_offintr(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030{
Al Viro3e577a82006-12-06 18:41:45 +00002031 stlport_t *portp = container_of(work, stlport_t, tqueue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 struct tty_struct *tty;
2033 unsigned int oldsigs;
2034
Jiri Slabya0564e12006-12-08 02:38:37 -08002035 pr_debug("stl_offintr(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036
Jiri Slaby615e4a72006-12-08 02:38:38 -08002037 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 return;
2039
2040 tty = portp->tty;
Jiri Slaby615e4a72006-12-08 02:38:38 -08002041 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042 return;
2043
2044 lock_kernel();
2045 if (test_bit(ASYI_TXLOW, &portp->istate)) {
2046 tty_wakeup(tty);
2047 }
2048 if (test_bit(ASYI_DCDCHANGE, &portp->istate)) {
2049 clear_bit(ASYI_DCDCHANGE, &portp->istate);
2050 oldsigs = portp->sigs;
2051 portp->sigs = stl_getsignals(portp);
2052 if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
2053 wake_up_interruptible(&portp->open_wait);
2054 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
2055 if (portp->flags & ASYNC_CHECK_CD)
2056 tty_hangup(tty); /* FIXME: module removal race here - AKPM */
2057 }
2058 }
2059 unlock_kernel();
2060}
2061
2062/*****************************************************************************/
2063
2064/*
2065 * Initialize all the ports on a panel.
2066 */
2067
2068static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
2069{
2070 stlport_t *portp;
2071 int chipmask, i;
2072
Jiri Slabya0564e12006-12-08 02:38:37 -08002073 pr_debug("stl_initports(brdp=%p,panelp=%p)\n", brdp, panelp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
2075 chipmask = stl_panelinit(brdp, panelp);
2076
2077/*
2078 * All UART's are initialized (if found!). Now go through and setup
2079 * each ports data structures.
2080 */
2081 for (i = 0; (i < panelp->nrports); i++) {
Tobias Klauserb0b4ed72006-03-31 02:30:56 -08002082 portp = kzalloc(sizeof(stlport_t), GFP_KERNEL);
2083 if (!portp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 printk("STALLION: failed to allocate memory "
Alan Coxb65b5b52006-06-27 02:54:05 -07002085 "(size=%Zd)\n", sizeof(stlport_t));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 break;
2087 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088
2089 portp->magic = STL_PORTMAGIC;
2090 portp->portnr = i;
2091 portp->brdnr = panelp->brdnr;
2092 portp->panelnr = panelp->panelnr;
2093 portp->uartp = panelp->uartp;
2094 portp->clk = brdp->clk;
2095 portp->baud_base = STL_BAUDBASE;
2096 portp->close_delay = STL_CLOSEDELAY;
2097 portp->closing_wait = 30 * HZ;
Al Viro3e577a82006-12-06 18:41:45 +00002098 INIT_WORK(&portp->tqueue, stl_offintr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 init_waitqueue_head(&portp->open_wait);
2100 init_waitqueue_head(&portp->close_wait);
2101 portp->stats.brd = portp->brdnr;
2102 portp->stats.panel = portp->panelnr;
2103 portp->stats.port = portp->portnr;
2104 panelp->ports[i] = portp;
2105 stl_portinit(brdp, panelp, portp);
2106 }
2107
2108 return(0);
2109}
2110
2111/*****************************************************************************/
2112
2113/*
2114 * Try to find and initialize an EasyIO board.
2115 */
2116
2117static inline int stl_initeio(stlbrd_t *brdp)
2118{
2119 stlpanel_t *panelp;
2120 unsigned int status;
2121 char *name;
2122 int rc;
2123
Jiri Slabya0564e12006-12-08 02:38:37 -08002124 pr_debug("stl_initeio(brdp=%p)\n", brdp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125
2126 brdp->ioctrl = brdp->ioaddr1 + 1;
2127 brdp->iostatus = brdp->ioaddr1 + 2;
2128
2129 status = inb(brdp->iostatus);
2130 if ((status & EIO_IDBITMASK) == EIO_MK3)
2131 brdp->ioctrl++;
2132
2133/*
2134 * Handle board specific stuff now. The real difference is PCI
2135 * or not PCI.
2136 */
2137 if (brdp->brdtype == BRD_EASYIOPCI) {
2138 brdp->iosize1 = 0x80;
2139 brdp->iosize2 = 0x80;
2140 name = "serial(EIO-PCI)";
2141 outb(0x41, (brdp->ioaddr2 + 0x4c));
2142 } else {
2143 brdp->iosize1 = 8;
2144 name = "serial(EIO)";
2145 if ((brdp->irq < 0) || (brdp->irq > 15) ||
2146 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
2147 printk("STALLION: invalid irq=%d for brd=%d\n",
2148 brdp->irq, brdp->brdnr);
2149 return(-EINVAL);
2150 }
2151 outb((stl_vecmap[brdp->irq] | EIO_0WS |
2152 ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)),
2153 brdp->ioctrl);
2154 }
2155
2156 if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) {
2157 printk(KERN_WARNING "STALLION: Warning, board %d I/O address "
2158 "%x conflicts with another device\n", brdp->brdnr,
2159 brdp->ioaddr1);
2160 return(-EBUSY);
2161 }
2162
2163 if (brdp->iosize2 > 0)
2164 if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) {
2165 printk(KERN_WARNING "STALLION: Warning, board %d I/O "
2166 "address %x conflicts with another device\n",
2167 brdp->brdnr, brdp->ioaddr2);
2168 printk(KERN_WARNING "STALLION: Warning, also "
2169 "releasing board %d I/O address %x \n",
2170 brdp->brdnr, brdp->ioaddr1);
2171 release_region(brdp->ioaddr1, brdp->iosize1);
2172 return(-EBUSY);
2173 }
2174
2175/*
2176 * Everything looks OK, so let's go ahead and probe for the hardware.
2177 */
2178 brdp->clk = CD1400_CLK;
2179 brdp->isr = stl_eiointr;
2180
2181 switch (status & EIO_IDBITMASK) {
2182 case EIO_8PORTM:
2183 brdp->clk = CD1400_CLK8M;
2184 /* fall thru */
2185 case EIO_8PORTRS:
2186 case EIO_8PORTDI:
2187 brdp->nrports = 8;
2188 break;
2189 case EIO_4PORTRS:
2190 brdp->nrports = 4;
2191 break;
2192 case EIO_MK3:
2193 switch (status & EIO_BRDMASK) {
2194 case ID_BRD4:
2195 brdp->nrports = 4;
2196 break;
2197 case ID_BRD8:
2198 brdp->nrports = 8;
2199 break;
2200 case ID_BRD16:
2201 brdp->nrports = 16;
2202 break;
2203 default:
2204 return(-ENODEV);
2205 }
2206 break;
2207 default:
2208 return(-ENODEV);
2209 }
2210
2211/*
2212 * We have verified that the board is actually present, so now we
2213 * can complete the setup.
2214 */
2215
Tobias Klauserb0b4ed72006-03-31 02:30:56 -08002216 panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
2217 if (!panelp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218 printk(KERN_WARNING "STALLION: failed to allocate memory "
Alan Coxb65b5b52006-06-27 02:54:05 -07002219 "(size=%Zd)\n", sizeof(stlpanel_t));
Tobias Klauserb0b4ed72006-03-31 02:30:56 -08002220 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222
2223 panelp->magic = STL_PANELMAGIC;
2224 panelp->brdnr = brdp->brdnr;
2225 panelp->panelnr = 0;
2226 panelp->nrports = brdp->nrports;
2227 panelp->iobase = brdp->ioaddr1;
2228 panelp->hwid = status;
2229 if ((status & EIO_IDBITMASK) == EIO_MK3) {
Jiri Slaby615e4a72006-12-08 02:38:38 -08002230 panelp->uartp = &stl_sc26198uart;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 panelp->isr = stl_sc26198intr;
2232 } else {
Jiri Slaby615e4a72006-12-08 02:38:38 -08002233 panelp->uartp = &stl_cd1400uart;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 panelp->isr = stl_cd1400eiointr;
2235 }
2236
2237 brdp->panels[0] = panelp;
2238 brdp->nrpanels = 1;
2239 brdp->state |= BRD_FOUND;
2240 brdp->hwid = status;
Thomas Gleixner0f2ed4c2006-07-01 19:29:33 -07002241 if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242 printk("STALLION: failed to register interrupt "
2243 "routine for %s irq=%d\n", name, brdp->irq);
2244 rc = -ENODEV;
2245 } else {
2246 rc = 0;
2247 }
Jesper Juhl014c2542006-01-15 02:37:08 +01002248 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249}
2250
2251/*****************************************************************************/
2252
2253/*
2254 * Try to find an ECH board and initialize it. This code is capable of
2255 * dealing with all types of ECH board.
2256 */
2257
2258static inline int stl_initech(stlbrd_t *brdp)
2259{
2260 stlpanel_t *panelp;
2261 unsigned int status, nxtid, ioaddr, conflict;
2262 int panelnr, banknr, i;
2263 char *name;
2264
Jiri Slabya0564e12006-12-08 02:38:37 -08002265 pr_debug("stl_initech(brdp=%p)\n", brdp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266
2267 status = 0;
2268 conflict = 0;
2269
2270/*
2271 * Set up the initial board register contents for boards. This varies a
2272 * bit between the different board types. So we need to handle each
2273 * separately. Also do a check that the supplied IRQ is good.
2274 */
2275 switch (brdp->brdtype) {
2276
2277 case BRD_ECH:
2278 brdp->isr = stl_echatintr;
2279 brdp->ioctrl = brdp->ioaddr1 + 1;
2280 brdp->iostatus = brdp->ioaddr1 + 1;
2281 status = inb(brdp->iostatus);
2282 if ((status & ECH_IDBITMASK) != ECH_ID)
2283 return(-ENODEV);
2284 if ((brdp->irq < 0) || (brdp->irq > 15) ||
2285 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
2286 printk("STALLION: invalid irq=%d for brd=%d\n",
2287 brdp->irq, brdp->brdnr);
2288 return(-EINVAL);
2289 }
2290 status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1);
2291 status |= (stl_vecmap[brdp->irq] << 1);
2292 outb((status | ECH_BRDRESET), brdp->ioaddr1);
2293 brdp->ioctrlval = ECH_INTENABLE |
2294 ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE);
2295 for (i = 0; (i < 10); i++)
2296 outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
2297 brdp->iosize1 = 2;
2298 brdp->iosize2 = 32;
2299 name = "serial(EC8/32)";
2300 outb(status, brdp->ioaddr1);
2301 break;
2302
2303 case BRD_ECHMC:
2304 brdp->isr = stl_echmcaintr;
2305 brdp->ioctrl = brdp->ioaddr1 + 0x20;
2306 brdp->iostatus = brdp->ioctrl;
2307 status = inb(brdp->iostatus);
2308 if ((status & ECH_IDBITMASK) != ECH_ID)
2309 return(-ENODEV);
2310 if ((brdp->irq < 0) || (brdp->irq > 15) ||
2311 (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
2312 printk("STALLION: invalid irq=%d for brd=%d\n",
2313 brdp->irq, brdp->brdnr);
2314 return(-EINVAL);
2315 }
2316 outb(ECHMC_BRDRESET, brdp->ioctrl);
2317 outb(ECHMC_INTENABLE, brdp->ioctrl);
2318 brdp->iosize1 = 64;
2319 name = "serial(EC8/32-MC)";
2320 break;
2321
2322 case BRD_ECHPCI:
2323 brdp->isr = stl_echpciintr;
2324 brdp->ioctrl = brdp->ioaddr1 + 2;
2325 brdp->iosize1 = 4;
2326 brdp->iosize2 = 8;
2327 name = "serial(EC8/32-PCI)";
2328 break;
2329
2330 case BRD_ECH64PCI:
2331 brdp->isr = stl_echpci64intr;
2332 brdp->ioctrl = brdp->ioaddr2 + 0x40;
2333 outb(0x43, (brdp->ioaddr1 + 0x4c));
2334 brdp->iosize1 = 0x80;
2335 brdp->iosize2 = 0x80;
2336 name = "serial(EC8/64-PCI)";
2337 break;
2338
2339 default:
2340 printk("STALLION: unknown board type=%d\n", brdp->brdtype);
2341 return(-EINVAL);
2342 break;
2343 }
2344
2345/*
2346 * Check boards for possible IO address conflicts and return fail status
2347 * if an IO conflict found.
2348 */
2349 if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) {
2350 printk(KERN_WARNING "STALLION: Warning, board %d I/O address "
2351 "%x conflicts with another device\n", brdp->brdnr,
2352 brdp->ioaddr1);
2353 return(-EBUSY);
2354 }
2355
2356 if (brdp->iosize2 > 0)
2357 if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) {
2358 printk(KERN_WARNING "STALLION: Warning, board %d I/O "
2359 "address %x conflicts with another device\n",
2360 brdp->brdnr, brdp->ioaddr2);
2361 printk(KERN_WARNING "STALLION: Warning, also "
2362 "releasing board %d I/O address %x \n",
2363 brdp->brdnr, brdp->ioaddr1);
2364 release_region(brdp->ioaddr1, brdp->iosize1);
2365 return(-EBUSY);
2366 }
2367
2368/*
2369 * Scan through the secondary io address space looking for panels.
2370 * As we find'em allocate and initialize panel structures for each.
2371 */
2372 brdp->clk = CD1400_CLK;
2373 brdp->hwid = status;
2374
2375 ioaddr = brdp->ioaddr2;
2376 banknr = 0;
2377 panelnr = 0;
2378 nxtid = 0;
2379
2380 for (i = 0; (i < STL_MAXPANELS); i++) {
2381 if (brdp->brdtype == BRD_ECHPCI) {
2382 outb(nxtid, brdp->ioctrl);
2383 ioaddr = brdp->ioaddr2;
2384 }
2385 status = inb(ioaddr + ECH_PNLSTATUS);
2386 if ((status & ECH_PNLIDMASK) != nxtid)
2387 break;
Tobias Klauserb0b4ed72006-03-31 02:30:56 -08002388 panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
2389 if (!panelp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390 printk("STALLION: failed to allocate memory "
Alan Coxb65b5b52006-06-27 02:54:05 -07002391 "(size=%Zd)\n", sizeof(stlpanel_t));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 break;
2393 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394 panelp->magic = STL_PANELMAGIC;
2395 panelp->brdnr = brdp->brdnr;
2396 panelp->panelnr = panelnr;
2397 panelp->iobase = ioaddr;
2398 panelp->pagenr = nxtid;
2399 panelp->hwid = status;
2400 brdp->bnk2panel[banknr] = panelp;
2401 brdp->bnkpageaddr[banknr] = nxtid;
2402 brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS;
2403
2404 if (status & ECH_PNLXPID) {
Jiri Slaby615e4a72006-12-08 02:38:38 -08002405 panelp->uartp = &stl_sc26198uart;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 panelp->isr = stl_sc26198intr;
2407 if (status & ECH_PNL16PORT) {
2408 panelp->nrports = 16;
2409 brdp->bnk2panel[banknr] = panelp;
2410 brdp->bnkpageaddr[banknr] = nxtid;
2411 brdp->bnkstataddr[banknr++] = ioaddr + 4 +
2412 ECH_PNLSTATUS;
2413 } else {
2414 panelp->nrports = 8;
2415 }
2416 } else {
Jiri Slaby615e4a72006-12-08 02:38:38 -08002417 panelp->uartp = &stl_cd1400uart;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418 panelp->isr = stl_cd1400echintr;
2419 if (status & ECH_PNL16PORT) {
2420 panelp->nrports = 16;
2421 panelp->ackmask = 0x80;
2422 if (brdp->brdtype != BRD_ECHPCI)
2423 ioaddr += EREG_BANKSIZE;
2424 brdp->bnk2panel[banknr] = panelp;
2425 brdp->bnkpageaddr[banknr] = ++nxtid;
2426 brdp->bnkstataddr[banknr++] = ioaddr +
2427 ECH_PNLSTATUS;
2428 } else {
2429 panelp->nrports = 8;
2430 panelp->ackmask = 0xc0;
2431 }
2432 }
2433
2434 nxtid++;
2435 ioaddr += EREG_BANKSIZE;
2436 brdp->nrports += panelp->nrports;
2437 brdp->panels[panelnr++] = panelp;
2438 if ((brdp->brdtype != BRD_ECHPCI) &&
2439 (ioaddr >= (brdp->ioaddr2 + brdp->iosize2)))
2440 break;
2441 }
2442
2443 brdp->nrpanels = panelnr;
2444 brdp->nrbnks = banknr;
2445 if (brdp->brdtype == BRD_ECH)
2446 outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
2447
2448 brdp->state |= BRD_FOUND;
Thomas Gleixner0f2ed4c2006-07-01 19:29:33 -07002449 if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450 printk("STALLION: failed to register interrupt "
2451 "routine for %s irq=%d\n", name, brdp->irq);
2452 i = -ENODEV;
2453 } else {
2454 i = 0;
2455 }
2456
2457 return(i);
2458}
2459
2460/*****************************************************************************/
2461
2462/*
2463 * Initialize and configure the specified board.
2464 * Scan through all the boards in the configuration and see what we
2465 * can find. Handle EIO and the ECH boards a little differently here
2466 * since the initial search and setup is very different.
2467 */
2468
2469static int __init stl_brdinit(stlbrd_t *brdp)
2470{
2471 int i;
2472
Jiri Slabya0564e12006-12-08 02:38:37 -08002473 pr_debug("stl_brdinit(brdp=%p)\n", brdp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474
2475 switch (brdp->brdtype) {
2476 case BRD_EASYIO:
2477 case BRD_EASYIOPCI:
2478 stl_initeio(brdp);
2479 break;
2480 case BRD_ECH:
2481 case BRD_ECHMC:
2482 case BRD_ECHPCI:
2483 case BRD_ECH64PCI:
2484 stl_initech(brdp);
2485 break;
2486 default:
2487 printk("STALLION: board=%d is unknown board type=%d\n",
2488 brdp->brdnr, brdp->brdtype);
2489 return(ENODEV);
2490 }
2491
2492 stl_brds[brdp->brdnr] = brdp;
2493 if ((brdp->state & BRD_FOUND) == 0) {
2494 printk("STALLION: %s board not found, board=%d io=%x irq=%d\n",
2495 stl_brdnames[brdp->brdtype], brdp->brdnr,
2496 brdp->ioaddr1, brdp->irq);
2497 return(ENODEV);
2498 }
2499
2500 for (i = 0; (i < STL_MAXPANELS); i++)
Jiri Slaby615e4a72006-12-08 02:38:38 -08002501 if (brdp->panels[i] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 stl_initports(brdp, brdp->panels[i]);
2503
2504 printk("STALLION: %s found, board=%d io=%x irq=%d "
2505 "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype],
2506 brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels,
2507 brdp->nrports);
2508 return(0);
2509}
2510
2511/*****************************************************************************/
2512
2513/*
2514 * Find the next available board number that is free.
2515 */
2516
2517static inline int stl_getbrdnr(void)
2518{
2519 int i;
2520
2521 for (i = 0; (i < STL_MAXBRDS); i++) {
Jiri Slaby615e4a72006-12-08 02:38:38 -08002522 if (stl_brds[i] == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 if (i >= stl_nrbrds)
2524 stl_nrbrds = i + 1;
2525 return(i);
2526 }
2527 }
2528 return(-1);
2529}
2530
2531/*****************************************************************************/
2532
2533#ifdef CONFIG_PCI
2534
2535/*
2536 * We have a Stallion board. Allocate a board structure and
2537 * initialize it. Read its IO and IRQ resources from PCI
2538 * configuration space.
2539 */
2540
2541static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
2542{
2543 stlbrd_t *brdp;
2544
Jiri Slabya0564e12006-12-08 02:38:37 -08002545 pr_debug("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 devp->bus->number, devp->devfn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547
2548 if (pci_enable_device(devp))
2549 return(-EIO);
Jiri Slaby615e4a72006-12-08 02:38:38 -08002550 if ((brdp = stl_allocbrd()) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 return(-ENOMEM);
2552 if ((brdp->brdnr = stl_getbrdnr()) < 0) {
2553 printk("STALLION: too many boards found, "
2554 "maximum supported %d\n", STL_MAXBRDS);
2555 return(0);
2556 }
2557 brdp->brdtype = brdtype;
2558
2559/*
2560 * Different Stallion boards use the BAR registers in different ways,
2561 * so set up io addresses based on board type.
2562 */
Jiri Slabya0564e12006-12-08 02:38:37 -08002563 pr_debug("%s(%d): BAR[]=%Lx,%Lx,%Lx,%Lx IRQ=%x\n", __FILE__, __LINE__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 pci_resource_start(devp, 0), pci_resource_start(devp, 1),
2565 pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566
2567/*
2568 * We have all resources from the board, so let's setup the actual
2569 * board structure now.
2570 */
2571 switch (brdtype) {
2572 case BRD_ECHPCI:
2573 brdp->ioaddr2 = pci_resource_start(devp, 0);
2574 brdp->ioaddr1 = pci_resource_start(devp, 1);
2575 break;
2576 case BRD_ECH64PCI:
2577 brdp->ioaddr2 = pci_resource_start(devp, 2);
2578 brdp->ioaddr1 = pci_resource_start(devp, 1);
2579 break;
2580 case BRD_EASYIOPCI:
2581 brdp->ioaddr1 = pci_resource_start(devp, 2);
2582 brdp->ioaddr2 = pci_resource_start(devp, 1);
2583 break;
2584 default:
2585 printk("STALLION: unknown PCI board type=%d\n", brdtype);
2586 break;
2587 }
2588
2589 brdp->irq = devp->irq;
2590 stl_brdinit(brdp);
2591
2592 return(0);
2593}
2594
2595/*****************************************************************************/
2596
2597/*
2598 * Find all Stallion PCI boards that might be installed. Initialize each
2599 * one as it is found.
2600 */
2601
2602
2603static inline int stl_findpcibrds(void)
2604{
2605 struct pci_dev *dev = NULL;
2606 int i, rc;
2607
Jiri Slabya0564e12006-12-08 02:38:37 -08002608 pr_debug("stl_findpcibrds()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609
2610 for (i = 0; (i < stl_nrpcibrds); i++)
2611 while ((dev = pci_find_device(stl_pcibrds[i].vendid,
2612 stl_pcibrds[i].devid, dev))) {
2613
2614/*
2615 * Found a device on the PCI bus that has our vendor and
2616 * device ID. Need to check now that it is really us.
2617 */
2618 if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
2619 continue;
2620
2621 rc = stl_initpcibrd(stl_pcibrds[i].brdtype, dev);
2622 if (rc)
2623 return(rc);
2624 }
2625
2626 return(0);
2627}
2628
2629#endif
2630
2631/*****************************************************************************/
2632
2633/*
2634 * Scan through all the boards in the configuration and see what we
2635 * can find. Handle EIO and the ECH boards a little differently here
2636 * since the initial search and setup is too different.
2637 */
2638
2639static inline int stl_initbrds(void)
2640{
2641 stlbrd_t *brdp;
2642 stlconf_t *confp;
2643 int i;
2644
Jiri Slabya0564e12006-12-08 02:38:37 -08002645 pr_debug("stl_initbrds()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646
2647 if (stl_nrbrds > STL_MAXBRDS) {
2648 printk("STALLION: too many boards in configuration table, "
2649 "truncating to %d\n", STL_MAXBRDS);
2650 stl_nrbrds = STL_MAXBRDS;
2651 }
2652
2653/*
2654 * Firstly scan the list of static boards configured. Allocate
2655 * resources and initialize the boards as found.
2656 */
2657 for (i = 0; (i < stl_nrbrds); i++) {
2658 confp = &stl_brdconf[i];
2659 stl_parsebrd(confp, stl_brdsp[i]);
Jiri Slaby615e4a72006-12-08 02:38:38 -08002660 if ((brdp = stl_allocbrd()) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 return(-ENOMEM);
2662 brdp->brdnr = i;
2663 brdp->brdtype = confp->brdtype;
2664 brdp->ioaddr1 = confp->ioaddr1;
2665 brdp->ioaddr2 = confp->ioaddr2;
2666 brdp->irq = confp->irq;
2667 brdp->irqtype = confp->irqtype;
2668 stl_brdinit(brdp);
2669 }
2670
2671/*
2672 * Find any dynamically supported boards. That is via module load
2673 * line options or auto-detected on the PCI bus.
2674 */
2675 stl_argbrds();
2676#ifdef CONFIG_PCI
2677 stl_findpcibrds();
2678#endif
2679
2680 return(0);
2681}
2682
2683/*****************************************************************************/
2684
2685/*
2686 * Return the board stats structure to user app.
2687 */
2688
2689static int stl_getbrdstats(combrd_t __user *bp)
2690{
2691 stlbrd_t *brdp;
2692 stlpanel_t *panelp;
2693 int i;
2694
2695 if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t)))
2696 return -EFAULT;
2697 if (stl_brdstats.brd >= STL_MAXBRDS)
2698 return(-ENODEV);
2699 brdp = stl_brds[stl_brdstats.brd];
Jiri Slaby615e4a72006-12-08 02:38:38 -08002700 if (brdp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701 return(-ENODEV);
2702
2703 memset(&stl_brdstats, 0, sizeof(combrd_t));
2704 stl_brdstats.brd = brdp->brdnr;
2705 stl_brdstats.type = brdp->brdtype;
2706 stl_brdstats.hwid = brdp->hwid;
2707 stl_brdstats.state = brdp->state;
2708 stl_brdstats.ioaddr = brdp->ioaddr1;
2709 stl_brdstats.ioaddr2 = brdp->ioaddr2;
2710 stl_brdstats.irq = brdp->irq;
2711 stl_brdstats.nrpanels = brdp->nrpanels;
2712 stl_brdstats.nrports = brdp->nrports;
2713 for (i = 0; (i < brdp->nrpanels); i++) {
2714 panelp = brdp->panels[i];
2715 stl_brdstats.panels[i].panel = i;
2716 stl_brdstats.panels[i].hwid = panelp->hwid;
2717 stl_brdstats.panels[i].nrports = panelp->nrports;
2718 }
2719
2720 return copy_to_user(bp, &stl_brdstats, sizeof(combrd_t)) ? -EFAULT : 0;
2721}
2722
2723/*****************************************************************************/
2724
2725/*
2726 * Resolve the referenced port number into a port struct pointer.
2727 */
2728
2729static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
2730{
2731 stlbrd_t *brdp;
2732 stlpanel_t *panelp;
2733
2734 if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
Jiri Slaby615e4a72006-12-08 02:38:38 -08002735 return(NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 brdp = stl_brds[brdnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08002737 if (brdp == NULL)
2738 return(NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739 if ((panelnr < 0) || (panelnr >= brdp->nrpanels))
Jiri Slaby615e4a72006-12-08 02:38:38 -08002740 return(NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 panelp = brdp->panels[panelnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08002742 if (panelp == NULL)
2743 return(NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 if ((portnr < 0) || (portnr >= panelp->nrports))
Jiri Slaby615e4a72006-12-08 02:38:38 -08002745 return(NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746 return(panelp->ports[portnr]);
2747}
2748
2749/*****************************************************************************/
2750
2751/*
2752 * Return the port stats structure to user app. A NULL port struct
2753 * pointer passed in means that we need to find out from the app
2754 * what port to get stats for (used through board control device).
2755 */
2756
2757static int stl_getportstats(stlport_t *portp, comstats_t __user *cp)
2758{
2759 unsigned char *head, *tail;
2760 unsigned long flags;
2761
2762 if (!portp) {
2763 if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
2764 return -EFAULT;
2765 portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
2766 stl_comstats.port);
Jiri Slaby615e4a72006-12-08 02:38:38 -08002767 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768 return(-ENODEV);
2769 }
2770
2771 portp->stats.state = portp->istate;
2772 portp->stats.flags = portp->flags;
2773 portp->stats.hwid = portp->hwid;
2774
2775 portp->stats.ttystate = 0;
2776 portp->stats.cflags = 0;
2777 portp->stats.iflags = 0;
2778 portp->stats.oflags = 0;
2779 portp->stats.lflags = 0;
2780 portp->stats.rxbuffered = 0;
2781
Alan Coxb65b5b52006-06-27 02:54:05 -07002782 spin_lock_irqsave(&stallion_lock, flags);
Jiri Slaby615e4a72006-12-08 02:38:38 -08002783 if (portp->tty != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 if (portp->tty->driver_data == portp) {
2785 portp->stats.ttystate = portp->tty->flags;
Alan Cox33f0f882006-01-09 20:54:13 -08002786 /* No longer available as a statistic */
2787 portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */
Jiri Slaby615e4a72006-12-08 02:38:38 -08002788 if (portp->tty->termios != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789 portp->stats.cflags = portp->tty->termios->c_cflag;
2790 portp->stats.iflags = portp->tty->termios->c_iflag;
2791 portp->stats.oflags = portp->tty->termios->c_oflag;
2792 portp->stats.lflags = portp->tty->termios->c_lflag;
2793 }
2794 }
2795 }
Alan Coxb65b5b52006-06-27 02:54:05 -07002796 spin_unlock_irqrestore(&stallion_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797
2798 head = portp->tx.head;
2799 tail = portp->tx.tail;
2800 portp->stats.txbuffered = ((head >= tail) ? (head - tail) :
2801 (STL_TXBUFSIZE - (tail - head)));
2802
2803 portp->stats.signals = (unsigned long) stl_getsignals(portp);
2804
2805 return copy_to_user(cp, &portp->stats,
2806 sizeof(comstats_t)) ? -EFAULT : 0;
2807}
2808
2809/*****************************************************************************/
2810
2811/*
2812 * Clear the port stats structure. We also return it zeroed out...
2813 */
2814
2815static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp)
2816{
2817 if (!portp) {
2818 if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
2819 return -EFAULT;
2820 portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
2821 stl_comstats.port);
Jiri Slaby615e4a72006-12-08 02:38:38 -08002822 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 return(-ENODEV);
2824 }
2825
2826 memset(&portp->stats, 0, sizeof(comstats_t));
2827 portp->stats.brd = portp->brdnr;
2828 portp->stats.panel = portp->panelnr;
2829 portp->stats.port = portp->portnr;
2830 return copy_to_user(cp, &portp->stats,
2831 sizeof(comstats_t)) ? -EFAULT : 0;
2832}
2833
2834/*****************************************************************************/
2835
2836/*
2837 * Return the entire driver ports structure to a user app.
2838 */
2839
2840static int stl_getportstruct(stlport_t __user *arg)
2841{
2842 stlport_t *portp;
2843
2844 if (copy_from_user(&stl_dummyport, arg, sizeof(stlport_t)))
2845 return -EFAULT;
2846 portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
2847 stl_dummyport.portnr);
2848 if (!portp)
2849 return -ENODEV;
2850 return copy_to_user(arg, portp, sizeof(stlport_t)) ? -EFAULT : 0;
2851}
2852
2853/*****************************************************************************/
2854
2855/*
2856 * Return the entire driver board structure to a user app.
2857 */
2858
2859static int stl_getbrdstruct(stlbrd_t __user *arg)
2860{
2861 stlbrd_t *brdp;
2862
2863 if (copy_from_user(&stl_dummybrd, arg, sizeof(stlbrd_t)))
2864 return -EFAULT;
2865 if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
2866 return -ENODEV;
2867 brdp = stl_brds[stl_dummybrd.brdnr];
2868 if (!brdp)
2869 return(-ENODEV);
2870 return copy_to_user(arg, brdp, sizeof(stlbrd_t)) ? -EFAULT : 0;
2871}
2872
2873/*****************************************************************************/
2874
2875/*
2876 * The "staliomem" device is also required to do some special operations
2877 * on the board and/or ports. In this driver it is mostly used for stats
2878 * collection.
2879 */
2880
2881static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
2882{
2883 int brdnr, rc;
2884 void __user *argp = (void __user *)arg;
2885
Jiri Slabya0564e12006-12-08 02:38:37 -08002886 pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887
2888 brdnr = iminor(ip);
2889 if (brdnr >= STL_MAXBRDS)
2890 return(-ENODEV);
2891 rc = 0;
2892
2893 switch (cmd) {
2894 case COM_GETPORTSTATS:
2895 rc = stl_getportstats(NULL, argp);
2896 break;
2897 case COM_CLRPORTSTATS:
2898 rc = stl_clrportstats(NULL, argp);
2899 break;
2900 case COM_GETBRDSTATS:
2901 rc = stl_getbrdstats(argp);
2902 break;
2903 case COM_READPORT:
2904 rc = stl_getportstruct(argp);
2905 break;
2906 case COM_READBOARD:
2907 rc = stl_getbrdstruct(argp);
2908 break;
2909 default:
2910 rc = -ENOIOCTLCMD;
2911 break;
2912 }
2913
2914 return(rc);
2915}
2916
Jeff Dikeb68e31d2006-10-02 02:17:18 -07002917static const struct tty_operations stl_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 .open = stl_open,
2919 .close = stl_close,
2920 .write = stl_write,
2921 .put_char = stl_putchar,
2922 .flush_chars = stl_flushchars,
2923 .write_room = stl_writeroom,
2924 .chars_in_buffer = stl_charsinbuffer,
2925 .ioctl = stl_ioctl,
2926 .set_termios = stl_settermios,
2927 .throttle = stl_throttle,
2928 .unthrottle = stl_unthrottle,
2929 .stop = stl_stop,
2930 .start = stl_start,
2931 .hangup = stl_hangup,
2932 .flush_buffer = stl_flushbuffer,
2933 .break_ctl = stl_breakctl,
2934 .wait_until_sent = stl_waituntilsent,
2935 .send_xchar = stl_sendxchar,
2936 .read_proc = stl_readproc,
2937 .tiocmget = stl_tiocmget,
2938 .tiocmset = stl_tiocmset,
2939};
2940
2941/*****************************************************************************/
2942
Adrian Bunk408b6642005-05-01 08:59:29 -07002943static int __init stl_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944{
2945 int i;
2946 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
2947
Alan Coxeffc8b72006-06-28 04:26:51 -07002948 spin_lock_init(&stallion_lock);
2949 spin_lock_init(&brd_lock);
2950
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951 stl_initbrds();
2952
2953 stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
2954 if (!stl_serial)
2955 return -1;
2956
2957/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958 * Set up a character driver for per board stuff. This is mainly used
2959 * to do stats ioctls on the ports.
2960 */
2961 if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
2962 printk("STALLION: failed to register serial board device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963
gregkh@suse.deca8eca62005-03-23 09:53:09 -08002964 stallion_class = class_create(THIS_MODULE, "staliomem");
Greg Kroah-Hartman7c69ef72005-06-20 21:15:16 -07002965 for (i = 0; i < 4; i++)
Greg Kroah-Hartman53f46542005-10-27 22:25:43 -07002966 class_device_create(stallion_class, NULL,
2967 MKDEV(STL_SIOMEMMAJOR, i), NULL,
2968 "staliomem%d", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969
2970 stl_serial->owner = THIS_MODULE;
2971 stl_serial->driver_name = stl_drvname;
2972 stl_serial->name = "ttyE";
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973 stl_serial->major = STL_SERIALMAJOR;
2974 stl_serial->minor_start = 0;
2975 stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
2976 stl_serial->subtype = SERIAL_TYPE_NORMAL;
2977 stl_serial->init_termios = stl_deftermios;
2978 stl_serial->flags = TTY_DRIVER_REAL_RAW;
2979 tty_set_operations(stl_serial, &stl_ops);
2980
2981 if (tty_register_driver(stl_serial)) {
2982 put_tty_driver(stl_serial);
2983 printk("STALLION: failed to register serial driver\n");
2984 return -1;
2985 }
2986
Jesper Juhl014c2542006-01-15 02:37:08 +01002987 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988}
2989
2990/*****************************************************************************/
2991/* CD1400 HARDWARE FUNCTIONS */
2992/*****************************************************************************/
2993
2994/*
2995 * These functions get/set/update the registers of the cd1400 UARTs.
2996 * Access to the cd1400 registers is via an address/data io port pair.
2997 * (Maybe should make this inline...)
2998 */
2999
3000static int stl_cd1400getreg(stlport_t *portp, int regnr)
3001{
3002 outb((regnr + portp->uartaddr), portp->ioaddr);
Jesper Juhl014c2542006-01-15 02:37:08 +01003003 return inb(portp->ioaddr + EREG_DATA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004}
3005
3006static void stl_cd1400setreg(stlport_t *portp, int regnr, int value)
3007{
3008 outb((regnr + portp->uartaddr), portp->ioaddr);
3009 outb(value, portp->ioaddr + EREG_DATA);
3010}
3011
3012static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value)
3013{
3014 outb((regnr + portp->uartaddr), portp->ioaddr);
3015 if (inb(portp->ioaddr + EREG_DATA) != value) {
3016 outb(value, portp->ioaddr + EREG_DATA);
Jesper Juhl014c2542006-01-15 02:37:08 +01003017 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 }
Jesper Juhl014c2542006-01-15 02:37:08 +01003019 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020}
3021
3022/*****************************************************************************/
3023
3024/*
3025 * Inbitialize the UARTs in a panel. We don't care what sort of board
3026 * these ports are on - since the port io registers are almost
3027 * identical when dealing with ports.
3028 */
3029
3030static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
3031{
3032 unsigned int gfrcr;
3033 int chipmask, i, j;
3034 int nrchips, uartaddr, ioaddr;
Alan Coxb65b5b52006-06-27 02:54:05 -07003035 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036
Jiri Slabya0564e12006-12-08 02:38:37 -08003037 pr_debug("stl_panelinit(brdp=%p,panelp=%p)\n", brdp, panelp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038
Alan Coxb65b5b52006-06-27 02:54:05 -07003039 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 BRDENABLE(panelp->brdnr, panelp->pagenr);
3041
3042/*
3043 * Check that each chip is present and started up OK.
3044 */
3045 chipmask = 0;
3046 nrchips = panelp->nrports / CD1400_PORTS;
3047 for (i = 0; (i < nrchips); i++) {
3048 if (brdp->brdtype == BRD_ECHPCI) {
3049 outb((panelp->pagenr + (i >> 1)), brdp->ioctrl);
3050 ioaddr = panelp->iobase;
3051 } else {
3052 ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1));
3053 }
3054 uartaddr = (i & 0x01) ? 0x080 : 0;
3055 outb((GFRCR + uartaddr), ioaddr);
3056 outb(0, (ioaddr + EREG_DATA));
3057 outb((CCR + uartaddr), ioaddr);
3058 outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
3059 outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
3060 outb((GFRCR + uartaddr), ioaddr);
3061 for (j = 0; (j < CCR_MAXWAIT); j++) {
3062 if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0)
3063 break;
3064 }
3065 if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) {
3066 printk("STALLION: cd1400 not responding, "
3067 "brd=%d panel=%d chip=%d\n",
3068 panelp->brdnr, panelp->panelnr, i);
3069 continue;
3070 }
3071 chipmask |= (0x1 << i);
3072 outb((PPR + uartaddr), ioaddr);
3073 outb(PPR_SCALAR, (ioaddr + EREG_DATA));
3074 }
3075
3076 BRDDISABLE(panelp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003077 spin_unlock_irqrestore(&brd_lock, flags);
Jesper Juhl014c2542006-01-15 02:37:08 +01003078 return chipmask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079}
3080
3081/*****************************************************************************/
3082
3083/*
3084 * Initialize hardware specific port registers.
3085 */
3086
3087static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
3088{
Alan Coxb65b5b52006-06-27 02:54:05 -07003089 unsigned long flags;
Jiri Slabya0564e12006-12-08 02:38:37 -08003090 pr_debug("stl_cd1400portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp,
3091 panelp, portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092
Jiri Slaby615e4a72006-12-08 02:38:38 -08003093 if ((brdp == NULL) || (panelp == NULL) ||
3094 (portp == NULL))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095 return;
3096
Alan Coxb65b5b52006-06-27 02:54:05 -07003097 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098 portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) ||
3099 (portp->portnr < 8)) ? 0 : EREG_BANKSIZE);
3100 portp->uartaddr = (portp->portnr & 0x04) << 5;
3101 portp->pagenr = panelp->pagenr + (portp->portnr >> 3);
3102
3103 BRDENABLE(portp->brdnr, portp->pagenr);
3104 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3105 stl_cd1400setreg(portp, LIVR, (portp->portnr << 3));
3106 portp->hwid = stl_cd1400getreg(portp, GFRCR);
3107 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003108 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109}
3110
3111/*****************************************************************************/
3112
3113/*
3114 * Wait for the command register to be ready. We will poll this,
3115 * since it won't usually take too long to be ready.
3116 */
3117
3118static void stl_cd1400ccrwait(stlport_t *portp)
3119{
3120 int i;
3121
3122 for (i = 0; (i < CCR_MAXWAIT); i++) {
3123 if (stl_cd1400getreg(portp, CCR) == 0) {
3124 return;
3125 }
3126 }
3127
3128 printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n",
3129 portp->portnr, portp->panelnr, portp->brdnr);
3130}
3131
3132/*****************************************************************************/
3133
3134/*
3135 * Set up the cd1400 registers for a port based on the termios port
3136 * settings.
3137 */
3138
3139static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
3140{
3141 stlbrd_t *brdp;
3142 unsigned long flags;
3143 unsigned int clkdiv, baudrate;
3144 unsigned char cor1, cor2, cor3;
3145 unsigned char cor4, cor5, ccr;
3146 unsigned char srer, sreron, sreroff;
3147 unsigned char mcor1, mcor2, rtpr;
3148 unsigned char clk, div;
3149
3150 cor1 = 0;
3151 cor2 = 0;
3152 cor3 = 0;
3153 cor4 = 0;
3154 cor5 = 0;
3155 ccr = 0;
3156 rtpr = 0;
3157 clk = 0;
3158 div = 0;
3159 mcor1 = 0;
3160 mcor2 = 0;
3161 sreron = 0;
3162 sreroff = 0;
3163
3164 brdp = stl_brds[portp->brdnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08003165 if (brdp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166 return;
3167
3168/*
3169 * Set up the RX char ignore mask with those RX error types we
3170 * can ignore. We can get the cd1400 to help us out a little here,
3171 * it will ignore parity errors and breaks for us.
3172 */
3173 portp->rxignoremsk = 0;
3174 if (tiosp->c_iflag & IGNPAR) {
3175 portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN);
3176 cor1 |= COR1_PARIGNORE;
3177 }
3178 if (tiosp->c_iflag & IGNBRK) {
3179 portp->rxignoremsk |= ST_BREAK;
3180 cor4 |= COR4_IGNBRK;
3181 }
3182
3183 portp->rxmarkmsk = ST_OVERRUN;
3184 if (tiosp->c_iflag & (INPCK | PARMRK))
3185 portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING);
3186 if (tiosp->c_iflag & BRKINT)
3187 portp->rxmarkmsk |= ST_BREAK;
3188
3189/*
3190 * Go through the char size, parity and stop bits and set all the
3191 * option register appropriately.
3192 */
3193 switch (tiosp->c_cflag & CSIZE) {
3194 case CS5:
3195 cor1 |= COR1_CHL5;
3196 break;
3197 case CS6:
3198 cor1 |= COR1_CHL6;
3199 break;
3200 case CS7:
3201 cor1 |= COR1_CHL7;
3202 break;
3203 default:
3204 cor1 |= COR1_CHL8;
3205 break;
3206 }
3207
3208 if (tiosp->c_cflag & CSTOPB)
3209 cor1 |= COR1_STOP2;
3210 else
3211 cor1 |= COR1_STOP1;
3212
3213 if (tiosp->c_cflag & PARENB) {
3214 if (tiosp->c_cflag & PARODD)
3215 cor1 |= (COR1_PARENB | COR1_PARODD);
3216 else
3217 cor1 |= (COR1_PARENB | COR1_PAREVEN);
3218 } else {
3219 cor1 |= COR1_PARNONE;
3220 }
3221
3222/*
3223 * Set the RX FIFO threshold at 6 chars. This gives a bit of breathing
3224 * space for hardware flow control and the like. This should be set to
3225 * VMIN. Also here we will set the RX data timeout to 10ms - this should
3226 * really be based on VTIME.
3227 */
3228 cor3 |= FIFO_RXTHRESHOLD;
3229 rtpr = 2;
3230
3231/*
3232 * Calculate the baud rate timers. For now we will just assume that
3233 * the input and output baud are the same. Could have used a baud
3234 * table here, but this way we can generate virtually any baud rate
3235 * we like!
3236 */
3237 baudrate = tiosp->c_cflag & CBAUD;
3238 if (baudrate & CBAUDEX) {
3239 baudrate &= ~CBAUDEX;
3240 if ((baudrate < 1) || (baudrate > 4))
3241 tiosp->c_cflag &= ~CBAUDEX;
3242 else
3243 baudrate += 15;
3244 }
3245 baudrate = stl_baudrates[baudrate];
3246 if ((tiosp->c_cflag & CBAUD) == B38400) {
3247 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
3248 baudrate = 57600;
3249 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
3250 baudrate = 115200;
3251 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
3252 baudrate = 230400;
3253 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
3254 baudrate = 460800;
3255 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
3256 baudrate = (portp->baud_base / portp->custom_divisor);
3257 }
3258 if (baudrate > STL_CD1400MAXBAUD)
3259 baudrate = STL_CD1400MAXBAUD;
3260
3261 if (baudrate > 0) {
3262 for (clk = 0; (clk < CD1400_NUMCLKS); clk++) {
3263 clkdiv = ((portp->clk / stl_cd1400clkdivs[clk]) / baudrate);
3264 if (clkdiv < 0x100)
3265 break;
3266 }
3267 div = (unsigned char) clkdiv;
3268 }
3269
3270/*
3271 * Check what form of modem signaling is required and set it up.
3272 */
3273 if ((tiosp->c_cflag & CLOCAL) == 0) {
3274 mcor1 |= MCOR1_DCD;
3275 mcor2 |= MCOR2_DCD;
3276 sreron |= SRER_MODEM;
3277 portp->flags |= ASYNC_CHECK_CD;
3278 } else {
3279 portp->flags &= ~ASYNC_CHECK_CD;
3280 }
3281
3282/*
3283 * Setup cd1400 enhanced modes if we can. In particular we want to
3284 * handle as much of the flow control as possible automatically. As
3285 * well as saving a few CPU cycles it will also greatly improve flow
3286 * control reliability.
3287 */
3288 if (tiosp->c_iflag & IXON) {
3289 cor2 |= COR2_TXIBE;
3290 cor3 |= COR3_SCD12;
3291 if (tiosp->c_iflag & IXANY)
3292 cor2 |= COR2_IXM;
3293 }
3294
3295 if (tiosp->c_cflag & CRTSCTS) {
3296 cor2 |= COR2_CTSAE;
3297 mcor1 |= FIFO_RTSTHRESHOLD;
3298 }
3299
3300/*
3301 * All cd1400 register values calculated so go through and set
3302 * them all up.
3303 */
3304
Jiri Slabya0564e12006-12-08 02:38:37 -08003305 pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306 portp->portnr, portp->panelnr, portp->brdnr);
Jiri Slabya0564e12006-12-08 02:38:37 -08003307 pr_debug(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003308 cor1, cor2, cor3, cor4, cor5);
Jiri Slabya0564e12006-12-08 02:38:37 -08003309 pr_debug(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310 mcor1, mcor2, rtpr, sreron, sreroff);
Jiri Slabya0564e12006-12-08 02:38:37 -08003311 pr_debug(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
3312 pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
3314 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315
Alan Coxb65b5b52006-06-27 02:54:05 -07003316 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317 BRDENABLE(portp->brdnr, portp->pagenr);
3318 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3));
3319 srer = stl_cd1400getreg(portp, SRER);
3320 stl_cd1400setreg(portp, SRER, 0);
3321 if (stl_cd1400updatereg(portp, COR1, cor1))
3322 ccr = 1;
3323 if (stl_cd1400updatereg(portp, COR2, cor2))
3324 ccr = 1;
3325 if (stl_cd1400updatereg(portp, COR3, cor3))
3326 ccr = 1;
3327 if (ccr) {
3328 stl_cd1400ccrwait(portp);
3329 stl_cd1400setreg(portp, CCR, CCR_CORCHANGE);
3330 }
3331 stl_cd1400setreg(portp, COR4, cor4);
3332 stl_cd1400setreg(portp, COR5, cor5);
3333 stl_cd1400setreg(portp, MCOR1, mcor1);
3334 stl_cd1400setreg(portp, MCOR2, mcor2);
3335 if (baudrate > 0) {
3336 stl_cd1400setreg(portp, TCOR, clk);
3337 stl_cd1400setreg(portp, TBPR, div);
3338 stl_cd1400setreg(portp, RCOR, clk);
3339 stl_cd1400setreg(portp, RBPR, div);
3340 }
3341 stl_cd1400setreg(portp, SCHR1, tiosp->c_cc[VSTART]);
3342 stl_cd1400setreg(portp, SCHR2, tiosp->c_cc[VSTOP]);
3343 stl_cd1400setreg(portp, SCHR3, tiosp->c_cc[VSTART]);
3344 stl_cd1400setreg(portp, SCHR4, tiosp->c_cc[VSTOP]);
3345 stl_cd1400setreg(portp, RTPR, rtpr);
3346 mcor1 = stl_cd1400getreg(portp, MSVR1);
3347 if (mcor1 & MSVR1_DCD)
3348 portp->sigs |= TIOCM_CD;
3349 else
3350 portp->sigs &= ~TIOCM_CD;
3351 stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron));
3352 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003353 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354}
3355
3356/*****************************************************************************/
3357
3358/*
3359 * Set the state of the DTR and RTS signals.
3360 */
3361
3362static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts)
3363{
3364 unsigned char msvr1, msvr2;
3365 unsigned long flags;
3366
Jiri Slabya0564e12006-12-08 02:38:37 -08003367 pr_debug("stl_cd1400setsignals(portp=%p,dtr=%d,rts=%d)\n",
3368 portp, dtr, rts);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003369
3370 msvr1 = 0;
3371 msvr2 = 0;
3372 if (dtr > 0)
3373 msvr1 = MSVR1_DTR;
3374 if (rts > 0)
3375 msvr2 = MSVR2_RTS;
3376
Alan Coxb65b5b52006-06-27 02:54:05 -07003377 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378 BRDENABLE(portp->brdnr, portp->pagenr);
3379 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3380 if (rts >= 0)
3381 stl_cd1400setreg(portp, MSVR2, msvr2);
3382 if (dtr >= 0)
3383 stl_cd1400setreg(portp, MSVR1, msvr1);
3384 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003385 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386}
3387
3388/*****************************************************************************/
3389
3390/*
3391 * Return the state of the signals.
3392 */
3393
3394static int stl_cd1400getsignals(stlport_t *portp)
3395{
3396 unsigned char msvr1, msvr2;
3397 unsigned long flags;
3398 int sigs;
3399
Jiri Slabya0564e12006-12-08 02:38:37 -08003400 pr_debug("stl_cd1400getsignals(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003401
Alan Coxb65b5b52006-06-27 02:54:05 -07003402 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 BRDENABLE(portp->brdnr, portp->pagenr);
3404 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3405 msvr1 = stl_cd1400getreg(portp, MSVR1);
3406 msvr2 = stl_cd1400getreg(portp, MSVR2);
3407 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003408 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003409
3410 sigs = 0;
3411 sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0;
3412 sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0;
3413 sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0;
3414 sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0;
3415#if 0
3416 sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0;
3417 sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0;
3418#else
3419 sigs |= TIOCM_DSR;
3420#endif
Jesper Juhl014c2542006-01-15 02:37:08 +01003421 return sigs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422}
3423
3424/*****************************************************************************/
3425
3426/*
3427 * Enable/Disable the Transmitter and/or Receiver.
3428 */
3429
3430static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx)
3431{
3432 unsigned char ccr;
3433 unsigned long flags;
3434
Jiri Slabya0564e12006-12-08 02:38:37 -08003435 pr_debug("stl_cd1400enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx);
3436
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 ccr = 0;
3438
3439 if (tx == 0)
3440 ccr |= CCR_TXDISABLE;
3441 else if (tx > 0)
3442 ccr |= CCR_TXENABLE;
3443 if (rx == 0)
3444 ccr |= CCR_RXDISABLE;
3445 else if (rx > 0)
3446 ccr |= CCR_RXENABLE;
3447
Alan Coxb65b5b52006-06-27 02:54:05 -07003448 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 BRDENABLE(portp->brdnr, portp->pagenr);
3450 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3451 stl_cd1400ccrwait(portp);
3452 stl_cd1400setreg(portp, CCR, ccr);
3453 stl_cd1400ccrwait(portp);
3454 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003455 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456}
3457
3458/*****************************************************************************/
3459
3460/*
3461 * Start/stop the Transmitter and/or Receiver.
3462 */
3463
3464static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx)
3465{
3466 unsigned char sreron, sreroff;
3467 unsigned long flags;
3468
Jiri Slabya0564e12006-12-08 02:38:37 -08003469 pr_debug("stl_cd1400startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470
3471 sreron = 0;
3472 sreroff = 0;
3473 if (tx == 0)
3474 sreroff |= (SRER_TXDATA | SRER_TXEMPTY);
3475 else if (tx == 1)
3476 sreron |= SRER_TXDATA;
3477 else if (tx >= 2)
3478 sreron |= SRER_TXEMPTY;
3479 if (rx == 0)
3480 sreroff |= SRER_RXDATA;
3481 else if (rx > 0)
3482 sreron |= SRER_RXDATA;
3483
Alan Coxb65b5b52006-06-27 02:54:05 -07003484 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485 BRDENABLE(portp->brdnr, portp->pagenr);
3486 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3487 stl_cd1400setreg(portp, SRER,
3488 ((stl_cd1400getreg(portp, SRER) & ~sreroff) | sreron));
3489 BRDDISABLE(portp->brdnr);
3490 if (tx > 0)
3491 set_bit(ASYI_TXBUSY, &portp->istate);
Alan Coxb65b5b52006-06-27 02:54:05 -07003492 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493}
3494
3495/*****************************************************************************/
3496
3497/*
3498 * Disable all interrupts from this port.
3499 */
3500
3501static void stl_cd1400disableintrs(stlport_t *portp)
3502{
3503 unsigned long flags;
3504
Jiri Slabya0564e12006-12-08 02:38:37 -08003505 pr_debug("stl_cd1400disableintrs(portp=%p)\n", portp);
3506
Alan Coxb65b5b52006-06-27 02:54:05 -07003507 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003508 BRDENABLE(portp->brdnr, portp->pagenr);
3509 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3510 stl_cd1400setreg(portp, SRER, 0);
3511 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003512 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513}
3514
3515/*****************************************************************************/
3516
3517static void stl_cd1400sendbreak(stlport_t *portp, int len)
3518{
3519 unsigned long flags;
3520
Jiri Slabya0564e12006-12-08 02:38:37 -08003521 pr_debug("stl_cd1400sendbreak(portp=%p,len=%d)\n", portp, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003522
Alan Coxb65b5b52006-06-27 02:54:05 -07003523 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003524 BRDENABLE(portp->brdnr, portp->pagenr);
3525 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3526 stl_cd1400setreg(portp, SRER,
3527 ((stl_cd1400getreg(portp, SRER) & ~SRER_TXDATA) |
3528 SRER_TXEMPTY));
3529 BRDDISABLE(portp->brdnr);
3530 portp->brklen = len;
3531 if (len == 1)
3532 portp->stats.txbreaks++;
Alan Coxb65b5b52006-06-27 02:54:05 -07003533 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003534}
3535
3536/*****************************************************************************/
3537
3538/*
3539 * Take flow control actions...
3540 */
3541
3542static void stl_cd1400flowctrl(stlport_t *portp, int state)
3543{
3544 struct tty_struct *tty;
3545 unsigned long flags;
3546
Jiri Slabya0564e12006-12-08 02:38:37 -08003547 pr_debug("stl_cd1400flowctrl(portp=%p,state=%x)\n", portp, state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003548
Jiri Slaby615e4a72006-12-08 02:38:38 -08003549 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550 return;
3551 tty = portp->tty;
Jiri Slaby615e4a72006-12-08 02:38:38 -08003552 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553 return;
3554
Alan Coxb65b5b52006-06-27 02:54:05 -07003555 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556 BRDENABLE(portp->brdnr, portp->pagenr);
3557 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3558
3559 if (state) {
3560 if (tty->termios->c_iflag & IXOFF) {
3561 stl_cd1400ccrwait(portp);
3562 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
3563 portp->stats.rxxon++;
3564 stl_cd1400ccrwait(portp);
3565 }
3566/*
3567 * Question: should we return RTS to what it was before? It may
3568 * have been set by an ioctl... Suppose not, since if you have
3569 * hardware flow control set then it is pretty silly to go and
3570 * set the RTS line by hand.
3571 */
3572 if (tty->termios->c_cflag & CRTSCTS) {
3573 stl_cd1400setreg(portp, MCOR1,
3574 (stl_cd1400getreg(portp, MCOR1) |
3575 FIFO_RTSTHRESHOLD));
3576 stl_cd1400setreg(portp, MSVR2, MSVR2_RTS);
3577 portp->stats.rxrtson++;
3578 }
3579 } else {
3580 if (tty->termios->c_iflag & IXOFF) {
3581 stl_cd1400ccrwait(portp);
3582 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
3583 portp->stats.rxxoff++;
3584 stl_cd1400ccrwait(portp);
3585 }
3586 if (tty->termios->c_cflag & CRTSCTS) {
3587 stl_cd1400setreg(portp, MCOR1,
3588 (stl_cd1400getreg(portp, MCOR1) & 0xf0));
3589 stl_cd1400setreg(portp, MSVR2, 0);
3590 portp->stats.rxrtsoff++;
3591 }
3592 }
3593
3594 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003595 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596}
3597
3598/*****************************************************************************/
3599
3600/*
3601 * Send a flow control character...
3602 */
3603
3604static void stl_cd1400sendflow(stlport_t *portp, int state)
3605{
3606 struct tty_struct *tty;
3607 unsigned long flags;
3608
Jiri Slabya0564e12006-12-08 02:38:37 -08003609 pr_debug("stl_cd1400sendflow(portp=%p,state=%x)\n", portp, state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003610
Jiri Slaby615e4a72006-12-08 02:38:38 -08003611 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612 return;
3613 tty = portp->tty;
Jiri Slaby615e4a72006-12-08 02:38:38 -08003614 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615 return;
3616
Alan Coxb65b5b52006-06-27 02:54:05 -07003617 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618 BRDENABLE(portp->brdnr, portp->pagenr);
3619 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3620 if (state) {
3621 stl_cd1400ccrwait(portp);
3622 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1);
3623 portp->stats.rxxon++;
3624 stl_cd1400ccrwait(portp);
3625 } else {
3626 stl_cd1400ccrwait(portp);
3627 stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2);
3628 portp->stats.rxxoff++;
3629 stl_cd1400ccrwait(portp);
3630 }
3631 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003632 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633}
3634
3635/*****************************************************************************/
3636
3637static void stl_cd1400flush(stlport_t *portp)
3638{
3639 unsigned long flags;
3640
Jiri Slabya0564e12006-12-08 02:38:37 -08003641 pr_debug("stl_cd1400flush(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642
Jiri Slaby615e4a72006-12-08 02:38:38 -08003643 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644 return;
3645
Alan Coxb65b5b52006-06-27 02:54:05 -07003646 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003647 BRDENABLE(portp->brdnr, portp->pagenr);
3648 stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
3649 stl_cd1400ccrwait(portp);
3650 stl_cd1400setreg(portp, CCR, CCR_TXFLUSHFIFO);
3651 stl_cd1400ccrwait(portp);
3652 portp->tx.tail = portp->tx.head;
3653 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07003654 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655}
3656
3657/*****************************************************************************/
3658
3659/*
3660 * Return the current state of data flow on this port. This is only
3661 * really interresting when determining if data has fully completed
3662 * transmission or not... This is easy for the cd1400, it accurately
3663 * maintains the busy port flag.
3664 */
3665
3666static int stl_cd1400datastate(stlport_t *portp)
3667{
Jiri Slabya0564e12006-12-08 02:38:37 -08003668 pr_debug("stl_cd1400datastate(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669
Jiri Slaby615e4a72006-12-08 02:38:38 -08003670 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01003671 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672
Jesper Juhl014c2542006-01-15 02:37:08 +01003673 return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674}
3675
3676/*****************************************************************************/
3677
3678/*
3679 * Interrupt service routine for cd1400 EasyIO boards.
3680 */
3681
3682static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase)
3683{
3684 unsigned char svrtype;
3685
Jiri Slabya0564e12006-12-08 02:38:37 -08003686 pr_debug("stl_cd1400eiointr(panelp=%p,iobase=%x)\n", panelp, iobase);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003687
Alan Coxb65b5b52006-06-27 02:54:05 -07003688 spin_lock(&brd_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003689 outb(SVRR, iobase);
3690 svrtype = inb(iobase + EREG_DATA);
3691 if (panelp->nrports > 4) {
3692 outb((SVRR + 0x80), iobase);
3693 svrtype |= inb(iobase + EREG_DATA);
3694 }
3695
3696 if (svrtype & SVRR_RX)
3697 stl_cd1400rxisr(panelp, iobase);
3698 else if (svrtype & SVRR_TX)
3699 stl_cd1400txisr(panelp, iobase);
3700 else if (svrtype & SVRR_MDM)
3701 stl_cd1400mdmisr(panelp, iobase);
Alan Coxb65b5b52006-06-27 02:54:05 -07003702
3703 spin_unlock(&brd_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704}
3705
3706/*****************************************************************************/
3707
3708/*
3709 * Interrupt service routine for cd1400 panels.
3710 */
3711
3712static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase)
3713{
3714 unsigned char svrtype;
3715
Jiri Slabya0564e12006-12-08 02:38:37 -08003716 pr_debug("stl_cd1400echintr(panelp=%p,iobase=%x)\n", panelp, iobase);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717
3718 outb(SVRR, iobase);
3719 svrtype = inb(iobase + EREG_DATA);
3720 outb((SVRR + 0x80), iobase);
3721 svrtype |= inb(iobase + EREG_DATA);
3722 if (svrtype & SVRR_RX)
3723 stl_cd1400rxisr(panelp, iobase);
3724 else if (svrtype & SVRR_TX)
3725 stl_cd1400txisr(panelp, iobase);
3726 else if (svrtype & SVRR_MDM)
3727 stl_cd1400mdmisr(panelp, iobase);
3728}
3729
3730
3731/*****************************************************************************/
3732
3733/*
3734 * Unfortunately we need to handle breaks in the TX data stream, since
3735 * this is the only way to generate them on the cd1400.
3736 */
3737
3738static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr)
3739{
3740 if (portp->brklen == 1) {
3741 outb((COR2 + portp->uartaddr), ioaddr);
3742 outb((inb(ioaddr + EREG_DATA) | COR2_ETC),
3743 (ioaddr + EREG_DATA));
3744 outb((TDR + portp->uartaddr), ioaddr);
3745 outb(ETC_CMD, (ioaddr + EREG_DATA));
3746 outb(ETC_STARTBREAK, (ioaddr + EREG_DATA));
3747 outb((SRER + portp->uartaddr), ioaddr);
3748 outb((inb(ioaddr + EREG_DATA) & ~(SRER_TXDATA | SRER_TXEMPTY)),
3749 (ioaddr + EREG_DATA));
Jesper Juhl014c2542006-01-15 02:37:08 +01003750 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751 } else if (portp->brklen > 1) {
3752 outb((TDR + portp->uartaddr), ioaddr);
3753 outb(ETC_CMD, (ioaddr + EREG_DATA));
3754 outb(ETC_STOPBREAK, (ioaddr + EREG_DATA));
3755 portp->brklen = -1;
Jesper Juhl014c2542006-01-15 02:37:08 +01003756 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757 } else {
3758 outb((COR2 + portp->uartaddr), ioaddr);
3759 outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC),
3760 (ioaddr + EREG_DATA));
3761 portp->brklen = 0;
3762 }
Jesper Juhl014c2542006-01-15 02:37:08 +01003763 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764}
3765
3766/*****************************************************************************/
3767
3768/*
3769 * Transmit interrupt handler. This has gotta be fast! Handling TX
3770 * chars is pretty simple, stuff as many as possible from the TX buffer
3771 * into the cd1400 FIFO. Must also handle TX breaks here, since they
3772 * are embedded as commands in the data stream. Oh no, had to use a goto!
3773 * This could be optimized more, will do when I get time...
3774 * In practice it is possible that interrupts are enabled but that the
3775 * port has been hung up. Need to handle not having any TX buffer here,
3776 * this is done by using the side effect that head and tail will also
3777 * be NULL if the buffer has been freed.
3778 */
3779
3780static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr)
3781{
3782 stlport_t *portp;
3783 int len, stlen;
3784 char *head, *tail;
3785 unsigned char ioack, srer;
3786
Jiri Slabya0564e12006-12-08 02:38:37 -08003787 pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788
3789 ioack = inb(ioaddr + EREG_TXACK);
3790 if (((ioack & panelp->ackmask) != 0) ||
3791 ((ioack & ACK_TYPMASK) != ACK_TYPTX)) {
3792 printk("STALLION: bad TX interrupt ack value=%x\n", ioack);
3793 return;
3794 }
3795 portp = panelp->ports[(ioack >> 3)];
3796
3797/*
3798 * Unfortunately we need to handle breaks in the data stream, since
3799 * this is the only way to generate them on the cd1400. Do it now if
3800 * a break is to be sent.
3801 */
3802 if (portp->brklen != 0)
3803 if (stl_cd1400breakisr(portp, ioaddr))
3804 goto stl_txalldone;
3805
3806 head = portp->tx.head;
3807 tail = portp->tx.tail;
3808 len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
3809 if ((len == 0) || ((len < STL_TXBUFLOW) &&
3810 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
3811 set_bit(ASYI_TXLOW, &portp->istate);
3812 schedule_work(&portp->tqueue);
3813 }
3814
3815 if (len == 0) {
3816 outb((SRER + portp->uartaddr), ioaddr);
3817 srer = inb(ioaddr + EREG_DATA);
3818 if (srer & SRER_TXDATA) {
3819 srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY;
3820 } else {
3821 srer &= ~(SRER_TXDATA | SRER_TXEMPTY);
3822 clear_bit(ASYI_TXBUSY, &portp->istate);
3823 }
3824 outb(srer, (ioaddr + EREG_DATA));
3825 } else {
3826 len = MIN(len, CD1400_TXFIFOSIZE);
3827 portp->stats.txtotal += len;
3828 stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
3829 outb((TDR + portp->uartaddr), ioaddr);
3830 outsb((ioaddr + EREG_DATA), tail, stlen);
3831 len -= stlen;
3832 tail += stlen;
3833 if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
3834 tail = portp->tx.buf;
3835 if (len > 0) {
3836 outsb((ioaddr + EREG_DATA), tail, len);
3837 tail += len;
3838 }
3839 portp->tx.tail = tail;
3840 }
3841
3842stl_txalldone:
3843 outb((EOSRR + portp->uartaddr), ioaddr);
3844 outb(0, (ioaddr + EREG_DATA));
3845}
3846
3847/*****************************************************************************/
3848
3849/*
3850 * Receive character interrupt handler. Determine if we have good chars
3851 * or bad chars and then process appropriately. Good chars are easy
3852 * just shove the lot into the RX buffer and set all status byte to 0.
3853 * If a bad RX char then process as required. This routine needs to be
3854 * fast! In practice it is possible that we get an interrupt on a port
3855 * that is closed. This can happen on hangups - since they completely
3856 * shutdown a port not in user context. Need to handle this case.
3857 */
3858
3859static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
3860{
3861 stlport_t *portp;
3862 struct tty_struct *tty;
3863 unsigned int ioack, len, buflen;
3864 unsigned char status;
3865 char ch;
3866
Jiri Slabya0564e12006-12-08 02:38:37 -08003867 pr_debug("stl_cd1400rxisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868
3869 ioack = inb(ioaddr + EREG_RXACK);
3870 if ((ioack & panelp->ackmask) != 0) {
3871 printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
3872 return;
3873 }
3874 portp = panelp->ports[(ioack >> 3)];
3875 tty = portp->tty;
3876
3877 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
3878 outb((RDCR + portp->uartaddr), ioaddr);
3879 len = inb(ioaddr + EREG_DATA);
Alan Cox33f0f882006-01-09 20:54:13 -08003880 if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881 len = MIN(len, sizeof(stl_unwanted));
3882 outb((RDSR + portp->uartaddr), ioaddr);
3883 insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
3884 portp->stats.rxlost += len;
3885 portp->stats.rxtotal += len;
3886 } else {
3887 len = MIN(len, buflen);
3888 if (len > 0) {
Alan Cox33f0f882006-01-09 20:54:13 -08003889 unsigned char *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890 outb((RDSR + portp->uartaddr), ioaddr);
Alan Cox33f0f882006-01-09 20:54:13 -08003891 tty_prepare_flip_string(tty, &ptr, len);
3892 insb((ioaddr + EREG_DATA), ptr, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003893 tty_schedule_flip(tty);
3894 portp->stats.rxtotal += len;
3895 }
3896 }
3897 } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) {
3898 outb((RDSR + portp->uartaddr), ioaddr);
3899 status = inb(ioaddr + EREG_DATA);
3900 ch = inb(ioaddr + EREG_DATA);
3901 if (status & ST_PARITY)
3902 portp->stats.rxparity++;
3903 if (status & ST_FRAMING)
3904 portp->stats.rxframing++;
3905 if (status & ST_OVERRUN)
3906 portp->stats.rxoverrun++;
3907 if (status & ST_BREAK)
3908 portp->stats.rxbreaks++;
3909 if (status & ST_SCHARMASK) {
3910 if ((status & ST_SCHARMASK) == ST_SCHAR1)
3911 portp->stats.txxon++;
3912 if ((status & ST_SCHARMASK) == ST_SCHAR2)
3913 portp->stats.txxoff++;
3914 goto stl_rxalldone;
3915 }
Alan Cox33f0f882006-01-09 20:54:13 -08003916 if (tty != NULL && (portp->rxignoremsk & status) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 if (portp->rxmarkmsk & status) {
3918 if (status & ST_BREAK) {
3919 status = TTY_BREAK;
3920 if (portp->flags & ASYNC_SAK) {
3921 do_SAK(tty);
3922 BRDENABLE(portp->brdnr, portp->pagenr);
3923 }
3924 } else if (status & ST_PARITY) {
3925 status = TTY_PARITY;
3926 } else if (status & ST_FRAMING) {
3927 status = TTY_FRAME;
3928 } else if(status & ST_OVERRUN) {
3929 status = TTY_OVERRUN;
3930 } else {
3931 status = 0;
3932 }
3933 } else {
3934 status = 0;
3935 }
Alan Cox33f0f882006-01-09 20:54:13 -08003936 tty_insert_flip_char(tty, ch, status);
3937 tty_schedule_flip(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003938 }
3939 } else {
3940 printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
3941 return;
3942 }
3943
3944stl_rxalldone:
3945 outb((EOSRR + portp->uartaddr), ioaddr);
3946 outb(0, (ioaddr + EREG_DATA));
3947}
3948
3949/*****************************************************************************/
3950
3951/*
3952 * Modem interrupt handler. The is called when the modem signal line
3953 * (DCD) has changed state. Leave most of the work to the off-level
3954 * processing routine.
3955 */
3956
3957static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr)
3958{
3959 stlport_t *portp;
3960 unsigned int ioack;
3961 unsigned char misr;
3962
Jiri Slabya0564e12006-12-08 02:38:37 -08003963 pr_debug("stl_cd1400mdmisr(panelp=%p)\n", panelp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964
3965 ioack = inb(ioaddr + EREG_MDACK);
3966 if (((ioack & panelp->ackmask) != 0) ||
3967 ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) {
3968 printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack);
3969 return;
3970 }
3971 portp = panelp->ports[(ioack >> 3)];
3972
3973 outb((MISR + portp->uartaddr), ioaddr);
3974 misr = inb(ioaddr + EREG_DATA);
3975 if (misr & MISR_DCD) {
3976 set_bit(ASYI_DCDCHANGE, &portp->istate);
3977 schedule_work(&portp->tqueue);
3978 portp->stats.modem++;
3979 }
3980
3981 outb((EOSRR + portp->uartaddr), ioaddr);
3982 outb(0, (ioaddr + EREG_DATA));
3983}
3984
3985/*****************************************************************************/
3986/* SC26198 HARDWARE FUNCTIONS */
3987/*****************************************************************************/
3988
3989/*
3990 * These functions get/set/update the registers of the sc26198 UARTs.
3991 * Access to the sc26198 registers is via an address/data io port pair.
3992 * (Maybe should make this inline...)
3993 */
3994
3995static int stl_sc26198getreg(stlport_t *portp, int regnr)
3996{
3997 outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
Jesper Juhl014c2542006-01-15 02:37:08 +01003998 return inb(portp->ioaddr + XP_DATA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999}
4000
4001static void stl_sc26198setreg(stlport_t *portp, int regnr, int value)
4002{
4003 outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
4004 outb(value, (portp->ioaddr + XP_DATA));
4005}
4006
4007static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value)
4008{
4009 outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
4010 if (inb(portp->ioaddr + XP_DATA) != value) {
4011 outb(value, (portp->ioaddr + XP_DATA));
Jesper Juhl014c2542006-01-15 02:37:08 +01004012 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004013 }
Jesper Juhl014c2542006-01-15 02:37:08 +01004014 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015}
4016
4017/*****************************************************************************/
4018
4019/*
4020 * Functions to get and set the sc26198 global registers.
4021 */
4022
4023static int stl_sc26198getglobreg(stlport_t *portp, int regnr)
4024{
4025 outb(regnr, (portp->ioaddr + XP_ADDR));
Jesper Juhl014c2542006-01-15 02:37:08 +01004026 return inb(portp->ioaddr + XP_DATA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027}
4028
4029#if 0
4030static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value)
4031{
4032 outb(regnr, (portp->ioaddr + XP_ADDR));
4033 outb(value, (portp->ioaddr + XP_DATA));
4034}
4035#endif
4036
4037/*****************************************************************************/
4038
4039/*
4040 * Inbitialize the UARTs in a panel. We don't care what sort of board
4041 * these ports are on - since the port io registers are almost
4042 * identical when dealing with ports.
4043 */
4044
4045static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
4046{
4047 int chipmask, i;
4048 int nrchips, ioaddr;
4049
Jiri Slabya0564e12006-12-08 02:38:37 -08004050 pr_debug("stl_sc26198panelinit(brdp=%p,panelp=%p)\n", brdp, panelp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051
4052 BRDENABLE(panelp->brdnr, panelp->pagenr);
4053
4054/*
4055 * Check that each chip is present and started up OK.
4056 */
4057 chipmask = 0;
4058 nrchips = (panelp->nrports + 4) / SC26198_PORTS;
4059 if (brdp->brdtype == BRD_ECHPCI)
4060 outb(panelp->pagenr, brdp->ioctrl);
4061
4062 for (i = 0; (i < nrchips); i++) {
4063 ioaddr = panelp->iobase + (i * 4);
4064 outb(SCCR, (ioaddr + XP_ADDR));
4065 outb(CR_RESETALL, (ioaddr + XP_DATA));
4066 outb(TSTR, (ioaddr + XP_ADDR));
4067 if (inb(ioaddr + XP_DATA) != 0) {
4068 printk("STALLION: sc26198 not responding, "
4069 "brd=%d panel=%d chip=%d\n",
4070 panelp->brdnr, panelp->panelnr, i);
4071 continue;
4072 }
4073 chipmask |= (0x1 << i);
4074 outb(GCCR, (ioaddr + XP_ADDR));
4075 outb(GCCR_IVRTYPCHANACK, (ioaddr + XP_DATA));
4076 outb(WDTRCR, (ioaddr + XP_ADDR));
4077 outb(0xff, (ioaddr + XP_DATA));
4078 }
4079
4080 BRDDISABLE(panelp->brdnr);
Jesper Juhl014c2542006-01-15 02:37:08 +01004081 return chipmask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082}
4083
4084/*****************************************************************************/
4085
4086/*
4087 * Initialize hardware specific port registers.
4088 */
4089
4090static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
4091{
Jiri Slabya0564e12006-12-08 02:38:37 -08004092 pr_debug("stl_sc26198portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp,
4093 panelp, portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094
Jiri Slaby615e4a72006-12-08 02:38:38 -08004095 if ((brdp == NULL) || (panelp == NULL) ||
4096 (portp == NULL))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 return;
4098
4099 portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4);
4100 portp->uartaddr = (portp->portnr & 0x07) << 4;
4101 portp->pagenr = panelp->pagenr;
4102 portp->hwid = 0x1;
4103
4104 BRDENABLE(portp->brdnr, portp->pagenr);
4105 stl_sc26198setreg(portp, IOPCR, IOPCR_SETSIGS);
4106 BRDDISABLE(portp->brdnr);
4107}
4108
4109/*****************************************************************************/
4110
4111/*
4112 * Set up the sc26198 registers for a port based on the termios port
4113 * settings.
4114 */
4115
4116static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
4117{
4118 stlbrd_t *brdp;
4119 unsigned long flags;
4120 unsigned int baudrate;
4121 unsigned char mr0, mr1, mr2, clk;
4122 unsigned char imron, imroff, iopr, ipr;
4123
4124 mr0 = 0;
4125 mr1 = 0;
4126 mr2 = 0;
4127 clk = 0;
4128 iopr = 0;
4129 imron = 0;
4130 imroff = 0;
4131
4132 brdp = stl_brds[portp->brdnr];
Jiri Slaby615e4a72006-12-08 02:38:38 -08004133 if (brdp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004134 return;
4135
4136/*
4137 * Set up the RX char ignore mask with those RX error types we
4138 * can ignore.
4139 */
4140 portp->rxignoremsk = 0;
4141 if (tiosp->c_iflag & IGNPAR)
4142 portp->rxignoremsk |= (SR_RXPARITY | SR_RXFRAMING |
4143 SR_RXOVERRUN);
4144 if (tiosp->c_iflag & IGNBRK)
4145 portp->rxignoremsk |= SR_RXBREAK;
4146
4147 portp->rxmarkmsk = SR_RXOVERRUN;
4148 if (tiosp->c_iflag & (INPCK | PARMRK))
4149 portp->rxmarkmsk |= (SR_RXPARITY | SR_RXFRAMING);
4150 if (tiosp->c_iflag & BRKINT)
4151 portp->rxmarkmsk |= SR_RXBREAK;
4152
4153/*
4154 * Go through the char size, parity and stop bits and set all the
4155 * option register appropriately.
4156 */
4157 switch (tiosp->c_cflag & CSIZE) {
4158 case CS5:
4159 mr1 |= MR1_CS5;
4160 break;
4161 case CS6:
4162 mr1 |= MR1_CS6;
4163 break;
4164 case CS7:
4165 mr1 |= MR1_CS7;
4166 break;
4167 default:
4168 mr1 |= MR1_CS8;
4169 break;
4170 }
4171
4172 if (tiosp->c_cflag & CSTOPB)
4173 mr2 |= MR2_STOP2;
4174 else
4175 mr2 |= MR2_STOP1;
4176
4177 if (tiosp->c_cflag & PARENB) {
4178 if (tiosp->c_cflag & PARODD)
4179 mr1 |= (MR1_PARENB | MR1_PARODD);
4180 else
4181 mr1 |= (MR1_PARENB | MR1_PAREVEN);
4182 } else {
4183 mr1 |= MR1_PARNONE;
4184 }
4185
4186 mr1 |= MR1_ERRBLOCK;
4187
4188/*
4189 * Set the RX FIFO threshold at 8 chars. This gives a bit of breathing
4190 * space for hardware flow control and the like. This should be set to
4191 * VMIN.
4192 */
4193 mr2 |= MR2_RXFIFOHALF;
4194
4195/*
4196 * Calculate the baud rate timers. For now we will just assume that
4197 * the input and output baud are the same. The sc26198 has a fixed
4198 * baud rate table, so only discrete baud rates possible.
4199 */
4200 baudrate = tiosp->c_cflag & CBAUD;
4201 if (baudrate & CBAUDEX) {
4202 baudrate &= ~CBAUDEX;
4203 if ((baudrate < 1) || (baudrate > 4))
4204 tiosp->c_cflag &= ~CBAUDEX;
4205 else
4206 baudrate += 15;
4207 }
4208 baudrate = stl_baudrates[baudrate];
4209 if ((tiosp->c_cflag & CBAUD) == B38400) {
4210 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
4211 baudrate = 57600;
4212 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
4213 baudrate = 115200;
4214 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
4215 baudrate = 230400;
4216 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
4217 baudrate = 460800;
4218 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
4219 baudrate = (portp->baud_base / portp->custom_divisor);
4220 }
4221 if (baudrate > STL_SC26198MAXBAUD)
4222 baudrate = STL_SC26198MAXBAUD;
4223
4224 if (baudrate > 0) {
4225 for (clk = 0; (clk < SC26198_NRBAUDS); clk++) {
4226 if (baudrate <= sc26198_baudtable[clk])
4227 break;
4228 }
4229 }
4230
4231/*
4232 * Check what form of modem signaling is required and set it up.
4233 */
4234 if (tiosp->c_cflag & CLOCAL) {
4235 portp->flags &= ~ASYNC_CHECK_CD;
4236 } else {
4237 iopr |= IOPR_DCDCOS;
4238 imron |= IR_IOPORT;
4239 portp->flags |= ASYNC_CHECK_CD;
4240 }
4241
4242/*
4243 * Setup sc26198 enhanced modes if we can. In particular we want to
4244 * handle as much of the flow control as possible automatically. As
4245 * well as saving a few CPU cycles it will also greatly improve flow
4246 * control reliability.
4247 */
4248 if (tiosp->c_iflag & IXON) {
4249 mr0 |= MR0_SWFTX | MR0_SWFT;
4250 imron |= IR_XONXOFF;
4251 } else {
4252 imroff |= IR_XONXOFF;
4253 }
4254 if (tiosp->c_iflag & IXOFF)
4255 mr0 |= MR0_SWFRX;
4256
4257 if (tiosp->c_cflag & CRTSCTS) {
4258 mr2 |= MR2_AUTOCTS;
4259 mr1 |= MR1_AUTORTS;
4260 }
4261
4262/*
4263 * All sc26198 register values calculated so go through and set
4264 * them all up.
4265 */
4266
Jiri Slabya0564e12006-12-08 02:38:37 -08004267 pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268 portp->portnr, portp->panelnr, portp->brdnr);
Jiri Slabya0564e12006-12-08 02:38:37 -08004269 pr_debug(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk);
4270 pr_debug(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff);
4271 pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004272 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
4273 tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274
Alan Coxb65b5b52006-06-27 02:54:05 -07004275 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276 BRDENABLE(portp->brdnr, portp->pagenr);
4277 stl_sc26198setreg(portp, IMR, 0);
4278 stl_sc26198updatereg(portp, MR0, mr0);
4279 stl_sc26198updatereg(portp, MR1, mr1);
4280 stl_sc26198setreg(portp, SCCR, CR_RXERRBLOCK);
4281 stl_sc26198updatereg(portp, MR2, mr2);
4282 stl_sc26198updatereg(portp, IOPIOR,
4283 ((stl_sc26198getreg(portp, IOPIOR) & ~IPR_CHANGEMASK) | iopr));
4284
4285 if (baudrate > 0) {
4286 stl_sc26198setreg(portp, TXCSR, clk);
4287 stl_sc26198setreg(portp, RXCSR, clk);
4288 }
4289
4290 stl_sc26198setreg(portp, XONCR, tiosp->c_cc[VSTART]);
4291 stl_sc26198setreg(portp, XOFFCR, tiosp->c_cc[VSTOP]);
4292
4293 ipr = stl_sc26198getreg(portp, IPR);
4294 if (ipr & IPR_DCD)
4295 portp->sigs &= ~TIOCM_CD;
4296 else
4297 portp->sigs |= TIOCM_CD;
4298
4299 portp->imr = (portp->imr & ~imroff) | imron;
4300 stl_sc26198setreg(portp, IMR, portp->imr);
4301 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004302 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004303}
4304
4305/*****************************************************************************/
4306
4307/*
4308 * Set the state of the DTR and RTS signals.
4309 */
4310
4311static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts)
4312{
4313 unsigned char iopioron, iopioroff;
4314 unsigned long flags;
4315
Jiri Slabya0564e12006-12-08 02:38:37 -08004316 pr_debug("stl_sc26198setsignals(portp=%p,dtr=%d,rts=%d)\n", portp,
4317 dtr, rts);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318
4319 iopioron = 0;
4320 iopioroff = 0;
4321 if (dtr == 0)
4322 iopioroff |= IPR_DTR;
4323 else if (dtr > 0)
4324 iopioron |= IPR_DTR;
4325 if (rts == 0)
4326 iopioroff |= IPR_RTS;
4327 else if (rts > 0)
4328 iopioron |= IPR_RTS;
4329
Alan Coxb65b5b52006-06-27 02:54:05 -07004330 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331 BRDENABLE(portp->brdnr, portp->pagenr);
4332 stl_sc26198setreg(portp, IOPIOR,
4333 ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron));
4334 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004335 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336}
4337
4338/*****************************************************************************/
4339
4340/*
4341 * Return the state of the signals.
4342 */
4343
4344static int stl_sc26198getsignals(stlport_t *portp)
4345{
4346 unsigned char ipr;
4347 unsigned long flags;
4348 int sigs;
4349
Jiri Slabya0564e12006-12-08 02:38:37 -08004350 pr_debug("stl_sc26198getsignals(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004351
Alan Coxb65b5b52006-06-27 02:54:05 -07004352 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353 BRDENABLE(portp->brdnr, portp->pagenr);
4354 ipr = stl_sc26198getreg(portp, IPR);
4355 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004356 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357
4358 sigs = 0;
4359 sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD;
4360 sigs |= (ipr & IPR_CTS) ? 0 : TIOCM_CTS;
4361 sigs |= (ipr & IPR_DTR) ? 0: TIOCM_DTR;
4362 sigs |= (ipr & IPR_RTS) ? 0: TIOCM_RTS;
4363 sigs |= TIOCM_DSR;
Jesper Juhl014c2542006-01-15 02:37:08 +01004364 return sigs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365}
4366
4367/*****************************************************************************/
4368
4369/*
4370 * Enable/Disable the Transmitter and/or Receiver.
4371 */
4372
4373static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx)
4374{
4375 unsigned char ccr;
4376 unsigned long flags;
4377
Jiri Slabya0564e12006-12-08 02:38:37 -08004378 pr_debug("stl_sc26198enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx,tx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379
4380 ccr = portp->crenable;
4381 if (tx == 0)
4382 ccr &= ~CR_TXENABLE;
4383 else if (tx > 0)
4384 ccr |= CR_TXENABLE;
4385 if (rx == 0)
4386 ccr &= ~CR_RXENABLE;
4387 else if (rx > 0)
4388 ccr |= CR_RXENABLE;
4389
Alan Coxb65b5b52006-06-27 02:54:05 -07004390 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391 BRDENABLE(portp->brdnr, portp->pagenr);
4392 stl_sc26198setreg(portp, SCCR, ccr);
4393 BRDDISABLE(portp->brdnr);
4394 portp->crenable = ccr;
Alan Coxb65b5b52006-06-27 02:54:05 -07004395 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004396}
4397
4398/*****************************************************************************/
4399
4400/*
4401 * Start/stop the Transmitter and/or Receiver.
4402 */
4403
4404static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx)
4405{
4406 unsigned char imr;
4407 unsigned long flags;
4408
Jiri Slabya0564e12006-12-08 02:38:37 -08004409 pr_debug("stl_sc26198startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004410
4411 imr = portp->imr;
4412 if (tx == 0)
4413 imr &= ~IR_TXRDY;
4414 else if (tx == 1)
4415 imr |= IR_TXRDY;
4416 if (rx == 0)
4417 imr &= ~(IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG);
4418 else if (rx > 0)
4419 imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG;
4420
Alan Coxb65b5b52006-06-27 02:54:05 -07004421 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004422 BRDENABLE(portp->brdnr, portp->pagenr);
4423 stl_sc26198setreg(portp, IMR, imr);
4424 BRDDISABLE(portp->brdnr);
4425 portp->imr = imr;
4426 if (tx > 0)
4427 set_bit(ASYI_TXBUSY, &portp->istate);
Alan Coxb65b5b52006-06-27 02:54:05 -07004428 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429}
4430
4431/*****************************************************************************/
4432
4433/*
4434 * Disable all interrupts from this port.
4435 */
4436
4437static void stl_sc26198disableintrs(stlport_t *portp)
4438{
4439 unsigned long flags;
4440
Jiri Slabya0564e12006-12-08 02:38:37 -08004441 pr_debug("stl_sc26198disableintrs(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442
Alan Coxb65b5b52006-06-27 02:54:05 -07004443 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004444 BRDENABLE(portp->brdnr, portp->pagenr);
4445 portp->imr = 0;
4446 stl_sc26198setreg(portp, IMR, 0);
4447 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004448 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449}
4450
4451/*****************************************************************************/
4452
4453static void stl_sc26198sendbreak(stlport_t *portp, int len)
4454{
4455 unsigned long flags;
4456
Jiri Slabya0564e12006-12-08 02:38:37 -08004457 pr_debug("stl_sc26198sendbreak(portp=%p,len=%d)\n", portp, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458
Alan Coxb65b5b52006-06-27 02:54:05 -07004459 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460 BRDENABLE(portp->brdnr, portp->pagenr);
4461 if (len == 1) {
4462 stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK);
4463 portp->stats.txbreaks++;
4464 } else {
4465 stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK);
4466 }
4467 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004468 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004469}
4470
4471/*****************************************************************************/
4472
4473/*
4474 * Take flow control actions...
4475 */
4476
4477static void stl_sc26198flowctrl(stlport_t *portp, int state)
4478{
4479 struct tty_struct *tty;
4480 unsigned long flags;
4481 unsigned char mr0;
4482
Jiri Slabya0564e12006-12-08 02:38:37 -08004483 pr_debug("stl_sc26198flowctrl(portp=%p,state=%x)\n", portp, state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484
Jiri Slaby615e4a72006-12-08 02:38:38 -08004485 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 return;
4487 tty = portp->tty;
Jiri Slaby615e4a72006-12-08 02:38:38 -08004488 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489 return;
4490
Alan Coxb65b5b52006-06-27 02:54:05 -07004491 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004492 BRDENABLE(portp->brdnr, portp->pagenr);
4493
4494 if (state) {
4495 if (tty->termios->c_iflag & IXOFF) {
4496 mr0 = stl_sc26198getreg(portp, MR0);
4497 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4498 stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
4499 mr0 |= MR0_SWFRX;
4500 portp->stats.rxxon++;
4501 stl_sc26198wait(portp);
4502 stl_sc26198setreg(portp, MR0, mr0);
4503 }
4504/*
4505 * Question: should we return RTS to what it was before? It may
4506 * have been set by an ioctl... Suppose not, since if you have
4507 * hardware flow control set then it is pretty silly to go and
4508 * set the RTS line by hand.
4509 */
4510 if (tty->termios->c_cflag & CRTSCTS) {
4511 stl_sc26198setreg(portp, MR1,
4512 (stl_sc26198getreg(portp, MR1) | MR1_AUTORTS));
4513 stl_sc26198setreg(portp, IOPIOR,
4514 (stl_sc26198getreg(portp, IOPIOR) | IOPR_RTS));
4515 portp->stats.rxrtson++;
4516 }
4517 } else {
4518 if (tty->termios->c_iflag & IXOFF) {
4519 mr0 = stl_sc26198getreg(portp, MR0);
4520 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4521 stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
4522 mr0 &= ~MR0_SWFRX;
4523 portp->stats.rxxoff++;
4524 stl_sc26198wait(portp);
4525 stl_sc26198setreg(portp, MR0, mr0);
4526 }
4527 if (tty->termios->c_cflag & CRTSCTS) {
4528 stl_sc26198setreg(portp, MR1,
4529 (stl_sc26198getreg(portp, MR1) & ~MR1_AUTORTS));
4530 stl_sc26198setreg(portp, IOPIOR,
4531 (stl_sc26198getreg(portp, IOPIOR) & ~IOPR_RTS));
4532 portp->stats.rxrtsoff++;
4533 }
4534 }
4535
4536 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004537 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538}
4539
4540/*****************************************************************************/
4541
4542/*
4543 * Send a flow control character.
4544 */
4545
4546static void stl_sc26198sendflow(stlport_t *portp, int state)
4547{
4548 struct tty_struct *tty;
4549 unsigned long flags;
4550 unsigned char mr0;
4551
Jiri Slabya0564e12006-12-08 02:38:37 -08004552 pr_debug("stl_sc26198sendflow(portp=%p,state=%x)\n", portp, state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004553
Jiri Slaby615e4a72006-12-08 02:38:38 -08004554 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555 return;
4556 tty = portp->tty;
Jiri Slaby615e4a72006-12-08 02:38:38 -08004557 if (tty == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004558 return;
4559
Alan Coxb65b5b52006-06-27 02:54:05 -07004560 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004561 BRDENABLE(portp->brdnr, portp->pagenr);
4562 if (state) {
4563 mr0 = stl_sc26198getreg(portp, MR0);
4564 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4565 stl_sc26198setreg(portp, SCCR, CR_TXSENDXON);
4566 mr0 |= MR0_SWFRX;
4567 portp->stats.rxxon++;
4568 stl_sc26198wait(portp);
4569 stl_sc26198setreg(portp, MR0, mr0);
4570 } else {
4571 mr0 = stl_sc26198getreg(portp, MR0);
4572 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4573 stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF);
4574 mr0 &= ~MR0_SWFRX;
4575 portp->stats.rxxoff++;
4576 stl_sc26198wait(portp);
4577 stl_sc26198setreg(portp, MR0, mr0);
4578 }
4579 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004580 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581}
4582
4583/*****************************************************************************/
4584
4585static void stl_sc26198flush(stlport_t *portp)
4586{
4587 unsigned long flags;
4588
Jiri Slabya0564e12006-12-08 02:38:37 -08004589 pr_debug("stl_sc26198flush(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004590
Jiri Slaby615e4a72006-12-08 02:38:38 -08004591 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592 return;
4593
Alan Coxb65b5b52006-06-27 02:54:05 -07004594 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004595 BRDENABLE(portp->brdnr, portp->pagenr);
4596 stl_sc26198setreg(portp, SCCR, CR_TXRESET);
4597 stl_sc26198setreg(portp, SCCR, portp->crenable);
4598 BRDDISABLE(portp->brdnr);
4599 portp->tx.tail = portp->tx.head;
Alan Coxb65b5b52006-06-27 02:54:05 -07004600 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004601}
4602
4603/*****************************************************************************/
4604
4605/*
4606 * Return the current state of data flow on this port. This is only
4607 * really interresting when determining if data has fully completed
4608 * transmission or not... The sc26198 interrupt scheme cannot
4609 * determine when all data has actually drained, so we need to
4610 * check the port statusy register to be sure.
4611 */
4612
4613static int stl_sc26198datastate(stlport_t *portp)
4614{
4615 unsigned long flags;
4616 unsigned char sr;
4617
Jiri Slabya0564e12006-12-08 02:38:37 -08004618 pr_debug("stl_sc26198datastate(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619
Jiri Slaby615e4a72006-12-08 02:38:38 -08004620 if (portp == NULL)
Jesper Juhl014c2542006-01-15 02:37:08 +01004621 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004622 if (test_bit(ASYI_TXBUSY, &portp->istate))
Jesper Juhl014c2542006-01-15 02:37:08 +01004623 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004624
Alan Coxb65b5b52006-06-27 02:54:05 -07004625 spin_lock_irqsave(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004626 BRDENABLE(portp->brdnr, portp->pagenr);
4627 sr = stl_sc26198getreg(portp, SR);
4628 BRDDISABLE(portp->brdnr);
Alan Coxb65b5b52006-06-27 02:54:05 -07004629 spin_unlock_irqrestore(&brd_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630
Jesper Juhl014c2542006-01-15 02:37:08 +01004631 return (sr & SR_TXEMPTY) ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632}
4633
4634/*****************************************************************************/
4635
4636/*
4637 * Delay for a small amount of time, to give the sc26198 a chance
4638 * to process a command...
4639 */
4640
4641static void stl_sc26198wait(stlport_t *portp)
4642{
4643 int i;
4644
Jiri Slabya0564e12006-12-08 02:38:37 -08004645 pr_debug("stl_sc26198wait(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004646
Jiri Slaby615e4a72006-12-08 02:38:38 -08004647 if (portp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004648 return;
4649
4650 for (i = 0; (i < 20); i++)
4651 stl_sc26198getglobreg(portp, TSTR);
4652}
4653
4654/*****************************************************************************/
4655
4656/*
4657 * If we are TX flow controlled and in IXANY mode then we may
4658 * need to unflow control here. We gotta do this because of the
4659 * automatic flow control modes of the sc26198.
4660 */
4661
4662static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty)
4663{
4664 unsigned char mr0;
4665
4666 mr0 = stl_sc26198getreg(portp, MR0);
4667 stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX));
4668 stl_sc26198setreg(portp, SCCR, CR_HOSTXON);
4669 stl_sc26198wait(portp);
4670 stl_sc26198setreg(portp, MR0, mr0);
4671 clear_bit(ASYI_TXFLOWED, &portp->istate);
4672}
4673
4674/*****************************************************************************/
4675
4676/*
4677 * Interrupt service routine for sc26198 panels.
4678 */
4679
4680static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase)
4681{
4682 stlport_t *portp;
4683 unsigned int iack;
4684
Alan Coxb65b5b52006-06-27 02:54:05 -07004685 spin_lock(&brd_lock);
4686
Linus Torvalds1da177e2005-04-16 15:20:36 -07004687/*
4688 * Work around bug in sc26198 chip... Cannot have A6 address
4689 * line of UART high, else iack will be returned as 0.
4690 */
4691 outb(0, (iobase + 1));
4692
4693 iack = inb(iobase + XP_IACK);
4694 portp = panelp->ports[(iack & IVR_CHANMASK) + ((iobase & 0x4) << 1)];
4695
4696 if (iack & IVR_RXDATA)
4697 stl_sc26198rxisr(portp, iack);
4698 else if (iack & IVR_TXDATA)
4699 stl_sc26198txisr(portp);
4700 else
4701 stl_sc26198otherisr(portp, iack);
Alan Coxb65b5b52006-06-27 02:54:05 -07004702
4703 spin_unlock(&brd_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004704}
4705
4706/*****************************************************************************/
4707
4708/*
4709 * Transmit interrupt handler. This has gotta be fast! Handling TX
4710 * chars is pretty simple, stuff as many as possible from the TX buffer
4711 * into the sc26198 FIFO.
4712 * In practice it is possible that interrupts are enabled but that the
4713 * port has been hung up. Need to handle not having any TX buffer here,
4714 * this is done by using the side effect that head and tail will also
4715 * be NULL if the buffer has been freed.
4716 */
4717
4718static void stl_sc26198txisr(stlport_t *portp)
4719{
4720 unsigned int ioaddr;
4721 unsigned char mr0;
4722 int len, stlen;
4723 char *head, *tail;
4724
Jiri Slabya0564e12006-12-08 02:38:37 -08004725 pr_debug("stl_sc26198txisr(portp=%p)\n", portp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004726
4727 ioaddr = portp->ioaddr;
4728 head = portp->tx.head;
4729 tail = portp->tx.tail;
4730 len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head));
4731 if ((len == 0) || ((len < STL_TXBUFLOW) &&
4732 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
4733 set_bit(ASYI_TXLOW, &portp->istate);
4734 schedule_work(&portp->tqueue);
4735 }
4736
4737 if (len == 0) {
4738 outb((MR0 | portp->uartaddr), (ioaddr + XP_ADDR));
4739 mr0 = inb(ioaddr + XP_DATA);
4740 if ((mr0 & MR0_TXMASK) == MR0_TXEMPTY) {
4741 portp->imr &= ~IR_TXRDY;
4742 outb((IMR | portp->uartaddr), (ioaddr + XP_ADDR));
4743 outb(portp->imr, (ioaddr + XP_DATA));
4744 clear_bit(ASYI_TXBUSY, &portp->istate);
4745 } else {
4746 mr0 |= ((mr0 & ~MR0_TXMASK) | MR0_TXEMPTY);
4747 outb(mr0, (ioaddr + XP_DATA));
4748 }
4749 } else {
4750 len = MIN(len, SC26198_TXFIFOSIZE);
4751 portp->stats.txtotal += len;
4752 stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
4753 outb(GTXFIFO, (ioaddr + XP_ADDR));
4754 outsb((ioaddr + XP_DATA), tail, stlen);
4755 len -= stlen;
4756 tail += stlen;
4757 if (tail >= (portp->tx.buf + STL_TXBUFSIZE))
4758 tail = portp->tx.buf;
4759 if (len > 0) {
4760 outsb((ioaddr + XP_DATA), tail, len);
4761 tail += len;
4762 }
4763 portp->tx.tail = tail;
4764 }
4765}
4766
4767/*****************************************************************************/
4768
4769/*
4770 * Receive character interrupt handler. Determine if we have good chars
4771 * or bad chars and then process appropriately. Good chars are easy
4772 * just shove the lot into the RX buffer and set all status byte to 0.
4773 * If a bad RX char then process as required. This routine needs to be
4774 * fast! In practice it is possible that we get an interrupt on a port
4775 * that is closed. This can happen on hangups - since they completely
4776 * shutdown a port not in user context. Need to handle this case.
4777 */
4778
4779static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
4780{
4781 struct tty_struct *tty;
4782 unsigned int len, buflen, ioaddr;
4783
Jiri Slabya0564e12006-12-08 02:38:37 -08004784 pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004785
4786 tty = portp->tty;
4787 ioaddr = portp->ioaddr;
4788 outb(GIBCR, (ioaddr + XP_ADDR));
4789 len = inb(ioaddr + XP_DATA) + 1;
4790
4791 if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
Alan Cox33f0f882006-01-09 20:54:13 -08004792 if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004793 len = MIN(len, sizeof(stl_unwanted));
4794 outb(GRXFIFO, (ioaddr + XP_ADDR));
4795 insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
4796 portp->stats.rxlost += len;
4797 portp->stats.rxtotal += len;
4798 } else {
4799 len = MIN(len, buflen);
4800 if (len > 0) {
Alan Cox33f0f882006-01-09 20:54:13 -08004801 unsigned char *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004802 outb(GRXFIFO, (ioaddr + XP_ADDR));
Alan Cox33f0f882006-01-09 20:54:13 -08004803 tty_prepare_flip_string(tty, &ptr, len);
4804 insb((ioaddr + XP_DATA), ptr, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004805 tty_schedule_flip(tty);
4806 portp->stats.rxtotal += len;
4807 }
4808 }
4809 } else {
4810 stl_sc26198rxbadchars(portp);
4811 }
4812
4813/*
4814 * If we are TX flow controlled and in IXANY mode then we may need
4815 * to unflow control here. We gotta do this because of the automatic
4816 * flow control modes of the sc26198.
4817 */
4818 if (test_bit(ASYI_TXFLOWED, &portp->istate)) {
Jiri Slaby615e4a72006-12-08 02:38:38 -08004819 if ((tty != NULL) &&
4820 (tty->termios != NULL) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004821 (tty->termios->c_iflag & IXANY)) {
4822 stl_sc26198txunflow(portp, tty);
4823 }
4824 }
4825}
4826
4827/*****************************************************************************/
4828
4829/*
4830 * Process an RX bad character.
4831 */
4832
4833static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch)
4834{
4835 struct tty_struct *tty;
4836 unsigned int ioaddr;
4837
4838 tty = portp->tty;
4839 ioaddr = portp->ioaddr;
4840
4841 if (status & SR_RXPARITY)
4842 portp->stats.rxparity++;
4843 if (status & SR_RXFRAMING)
4844 portp->stats.rxframing++;
4845 if (status & SR_RXOVERRUN)
4846 portp->stats.rxoverrun++;
4847 if (status & SR_RXBREAK)
4848 portp->stats.rxbreaks++;
4849
Jiri Slaby615e4a72006-12-08 02:38:38 -08004850 if ((tty != NULL) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004851 ((portp->rxignoremsk & status) == 0)) {
4852 if (portp->rxmarkmsk & status) {
4853 if (status & SR_RXBREAK) {
4854 status = TTY_BREAK;
4855 if (portp->flags & ASYNC_SAK) {
4856 do_SAK(tty);
4857 BRDENABLE(portp->brdnr, portp->pagenr);
4858 }
4859 } else if (status & SR_RXPARITY) {
4860 status = TTY_PARITY;
4861 } else if (status & SR_RXFRAMING) {
4862 status = TTY_FRAME;
4863 } else if(status & SR_RXOVERRUN) {
4864 status = TTY_OVERRUN;
4865 } else {
4866 status = 0;
4867 }
4868 } else {
4869 status = 0;
4870 }
4871
Alan Cox33f0f882006-01-09 20:54:13 -08004872 tty_insert_flip_char(tty, ch, status);
4873 tty_schedule_flip(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004874
4875 if (status == 0)
4876 portp->stats.rxtotal++;
4877 }
4878}
4879
4880/*****************************************************************************/
4881
4882/*
4883 * Process all characters in the RX FIFO of the UART. Check all char
4884 * status bytes as well, and process as required. We need to check
4885 * all bytes in the FIFO, in case some more enter the FIFO while we
4886 * are here. To get the exact character error type we need to switch
4887 * into CHAR error mode (that is why we need to make sure we empty
4888 * the FIFO).
4889 */
4890
4891static void stl_sc26198rxbadchars(stlport_t *portp)
4892{
4893 unsigned char status, mr1;
4894 char ch;
4895
4896/*
4897 * To get the precise error type for each character we must switch
4898 * back into CHAR error mode.
4899 */
4900 mr1 = stl_sc26198getreg(portp, MR1);
4901 stl_sc26198setreg(portp, MR1, (mr1 & ~MR1_ERRBLOCK));
4902
4903 while ((status = stl_sc26198getreg(portp, SR)) & SR_RXRDY) {
4904 stl_sc26198setreg(portp, SCCR, CR_CLEARRXERR);
4905 ch = stl_sc26198getreg(portp, RXFIFO);
4906 stl_sc26198rxbadch(portp, status, ch);
4907 }
4908
4909/*
4910 * To get correct interrupt class we must switch back into BLOCK
4911 * error mode.
4912 */
4913 stl_sc26198setreg(portp, MR1, mr1);
4914}
4915
4916/*****************************************************************************/
4917
4918/*
4919 * Other interrupt handler. This includes modem signals, flow
4920 * control actions, etc. Most stuff is left to off-level interrupt
4921 * processing time.
4922 */
4923
4924static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack)
4925{
4926 unsigned char cir, ipr, xisr;
4927
Jiri Slabya0564e12006-12-08 02:38:37 -08004928 pr_debug("stl_sc26198otherisr(portp=%p,iack=%x)\n", portp, iack);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004929
4930 cir = stl_sc26198getglobreg(portp, CIR);
4931
4932 switch (cir & CIR_SUBTYPEMASK) {
4933 case CIR_SUBCOS:
4934 ipr = stl_sc26198getreg(portp, IPR);
4935 if (ipr & IPR_DCDCHANGE) {
4936 set_bit(ASYI_DCDCHANGE, &portp->istate);
4937 schedule_work(&portp->tqueue);
4938 portp->stats.modem++;
4939 }
4940 break;
4941 case CIR_SUBXONXOFF:
4942 xisr = stl_sc26198getreg(portp, XISR);
4943 if (xisr & XISR_RXXONGOT) {
4944 set_bit(ASYI_TXFLOWED, &portp->istate);
4945 portp->stats.txxoff++;
4946 }
4947 if (xisr & XISR_RXXOFFGOT) {
4948 clear_bit(ASYI_TXFLOWED, &portp->istate);
4949 portp->stats.txxon++;
4950 }
4951 break;
4952 case CIR_SUBBREAK:
4953 stl_sc26198setreg(portp, SCCR, CR_BREAKRESET);
4954 stl_sc26198rxbadchars(portp);
4955 break;
4956 default:
4957 break;
4958 }
4959}
4960
4961/*****************************************************************************/