OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [char/] [riscom8.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *      linux/drivers/char/riscom.c  -- RISCom/8 multiport serial driver.
3
 *
4
 *      Copyright (C) 1994-1996  Dmitry Gorodchanin (pgmdsg@ibi.com)
5
 *
6
 *      This code is loosely based on the Linux serial driver, written by
7
 *      Linus Torvalds, Theodore T'so and others. The RISCom/8 card
8
 *      programming info was obtained from various drivers for other OSes
9
 *      (FreeBSD, ISC, etc), but no source code from those drivers were
10
 *      directly included in this driver.
11
 *
12
 *
13
 *      This program is free software; you can redistribute it and/or modify
14
 *      it under the terms of the GNU General Public License as published by
15
 *      the Free Software Foundation; either version 2 of the License, or
16
 *      (at your option) any later version.
17
 *
18
 *      This program is distributed in the hope that it will be useful,
19
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 *      GNU General Public License for more details.
22
 *
23
 *      You should have received a copy of the GNU General Public License
24
 *      along with this program; if not, write to the Free Software
25
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
 *
27
 *      Revision 1.1
28
 *
29
 *      ChangeLog:
30
 *      Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 27-Jun-2001
31
 *      - get rid of check_region and several cleanups
32
 */
33
 
34
#include <linux/module.h>
35
 
36
#include <asm/io.h>
37
#include <linux/kernel.h>
38
#include <linux/sched.h>
39
#include <linux/ioport.h>
40
#include <linux/interrupt.h>
41
#include <linux/errno.h>
42
#include <linux/tty.h>
43
#include <linux/mm.h>
44
#include <linux/serial.h>
45
#include <linux/fcntl.h>
46
#include <linux/major.h>
47
#include <linux/init.h>
48
#include <linux/delay.h>
49
#include <linux/tty_flip.h>
50
 
51
#include <asm/uaccess.h>
52
 
53
#include "riscom8.h"
54
#include "riscom8_reg.h"
55
 
56
/* Am I paranoid or not ? ;-) */
57
#define RISCOM_PARANOIA_CHECK
58
 
59
/*
60
 * Crazy InteliCom/8 boards sometimes has swapped CTS & DSR signals.
61
 * You can slightly speed up things by #undefing the following option,
62
 * if you are REALLY sure that your board is correct one.
63
 */
64
 
65
#define RISCOM_BRAIN_DAMAGED_CTS
66
 
67
/*
68
 * The following defines are mostly for testing purposes. But if you need
69
 * some nice reporting in your syslog, you can define them also.
70
 */
71
#undef RC_REPORT_FIFO
72
#undef RC_REPORT_OVERRUN
73
 
74
 
75
#define RISCOM_LEGAL_FLAGS \
76
        (ASYNC_HUP_NOTIFY   | ASYNC_SAK          | ASYNC_SPLIT_TERMIOS   | \
77
         ASYNC_SPD_HI       | ASYNC_SPEED_VHI    | ASYNC_SESSION_LOCKOUT | \
78
         ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
79
 
80
#define RS_EVENT_WRITE_WAKEUP   0
81
 
82
static struct tty_driver *riscom_driver;
83
 
84
static struct riscom_board rc_board[RC_NBOARD] =  {
85
        {
86
                .base   = RC_IOBASE1,
87
        },
88
        {
89
                .base   = RC_IOBASE2,
90
        },
91
        {
92
                .base   = RC_IOBASE3,
93
        },
94
        {
95
                .base   = RC_IOBASE4,
96
        },
97
};
98
 
99
static struct riscom_port rc_port[RC_NBOARD * RC_NPORT];
100
 
101
/* RISCom/8 I/O ports addresses (without address translation) */
102
static unsigned short rc_ioport[] =  {
103
#if 1
104
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c,
105
#else
106
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10,
107
        0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62,
108
        0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101
109
#endif
110
};
111
#define RC_NIOPORT      ARRAY_SIZE(rc_ioport)
112
 
113
 
114
static inline int rc_paranoia_check(struct riscom_port const * port,
115
                                    char *name, const char *routine)
116
{
117
#ifdef RISCOM_PARANOIA_CHECK
118
        static const char badmagic[] = KERN_INFO
119
                "rc: Warning: bad riscom port magic number for device %s in %s\n";
120
        static const char badinfo[] = KERN_INFO
121
                "rc: Warning: null riscom port for device %s in %s\n";
122
 
123
        if (!port) {
124
                printk(badinfo, name, routine);
125
                return 1;
126
        }
127
        if (port->magic != RISCOM8_MAGIC) {
128
                printk(badmagic, name, routine);
129
                return 1;
130
        }
131
#endif
132
        return 0;
133
}
134
 
135
/*
136
 *
137
 *  Service functions for RISCom/8 driver.
138
 *
139
 */
140
 
141
/* Get board number from pointer */
142
static inline int board_No (struct riscom_board const * bp)
143
{
144
        return bp - rc_board;
145
}
146
 
147
/* Get port number from pointer */
148
static inline int port_No (struct riscom_port const * port)
149
{
150
        return RC_PORT(port - rc_port);
151
}
152
 
153
/* Get pointer to board from pointer to port */
154
static inline struct riscom_board * port_Board(struct riscom_port const * port)
155
{
156
        return &rc_board[RC_BOARD(port - rc_port)];
157
}
158
 
159
/* Input Byte from CL CD180 register */
160
static inline unsigned char rc_in(struct riscom_board const * bp, unsigned short reg)
161
{
162
        return inb(bp->base + RC_TO_ISA(reg));
163
}
164
 
165
/* Output Byte to CL CD180 register */
166
static inline void rc_out(struct riscom_board const * bp, unsigned short reg,
167
                          unsigned char val)
168
{
169
        outb(val, bp->base + RC_TO_ISA(reg));
170
}
171
 
172
/* Wait for Channel Command Register ready */
173
static inline void rc_wait_CCR(struct riscom_board const * bp)
174
{
175
        unsigned long delay;
176
 
177
        /* FIXME: need something more descriptive then 100000 :) */
178
        for (delay = 100000; delay; delay--)
179
                if (!rc_in(bp, CD180_CCR))
180
                        return;
181
 
182
        printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp));
183
}
184
 
185
/*
186
 *  RISCom/8 probe functions.
187
 */
188
 
189
static inline int rc_request_io_range(struct riscom_board * const bp)
190
{
191
        int i;
192
 
193
        for (i = 0; i < RC_NIOPORT; i++)
194
                if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1,
195
                                   "RISCom/8"))  {
196
                        goto out_release;
197
                }
198
        return 0;
199
out_release:
200
        printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n",
201
                         board_No(bp), bp->base);
202
        while(--i >= 0)
203
                release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
204
        return 1;
205
}
206
 
207
static inline void rc_release_io_range(struct riscom_board * const bp)
208
{
209
        int i;
210
 
211
        for (i = 0; i < RC_NIOPORT; i++)
212
                release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
213
}
214
 
215
/* Reset and setup CD180 chip */
216
static void __init rc_init_CD180(struct riscom_board const * bp)
217
{
218
        unsigned long flags;
219
 
220
        save_flags(flags); cli();
221
        rc_out(bp, RC_CTOUT, 0);                    /* Clear timeout             */
222
        rc_wait_CCR(bp);                           /* Wait for CCR ready        */
223
        rc_out(bp, CD180_CCR, CCR_HARDRESET);      /* Reset CD180 chip          */
224
        sti();
225
        msleep(50);                                /* Delay 0.05 sec            */
226
        cli();
227
        rc_out(bp, CD180_GIVR, RC_ID);             /* Set ID for this chip      */
228
        rc_out(bp, CD180_GICR, 0);                 /* Clear all bits            */
229
        rc_out(bp, CD180_PILR1, RC_ACK_MINT);      /* Prio for modem intr       */
230
        rc_out(bp, CD180_PILR2, RC_ACK_TINT);      /* Prio for transmitter intr */
231
        rc_out(bp, CD180_PILR3, RC_ACK_RINT);      /* Prio for receiver intr    */
232
 
233
        /* Setting up prescaler. We need 4 ticks per 1 ms */
234
        rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8);
235
        rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff);
236
 
237
        restore_flags(flags);
238
}
239
 
240
/* Main probing routine, also sets irq. */
241
static int __init rc_probe(struct riscom_board *bp)
242
{
243
        unsigned char val1, val2;
244
        int irqs = 0;
245
        int retries;
246
 
247
        bp->irq = 0;
248
 
249
        if (rc_request_io_range(bp))
250
                return 1;
251
 
252
        /* Are the I/O ports here ? */
253
        rc_out(bp, CD180_PPRL, 0x5a);
254
        outb(0xff, 0x80);
255
        val1 = rc_in(bp, CD180_PPRL);
256
        rc_out(bp, CD180_PPRL, 0xa5);
257
        outb(0x00, 0x80);
258
        val2 = rc_in(bp, CD180_PPRL);
259
 
260
        if ((val1 != 0x5a) || (val2 != 0xa5))  {
261
                printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n",
262
                       board_No(bp), bp->base);
263
                goto out_release;
264
        }
265
 
266
        /* It's time to find IRQ for this board */
267
        for (retries = 0; retries < 5 && irqs <= 0; retries++)  {
268
                irqs = probe_irq_on();
269
                rc_init_CD180(bp);                      /* Reset CD180 chip       */
270
                rc_out(bp, CD180_CAR, 2);               /* Select port 2          */
271
                rc_wait_CCR(bp);
272
                rc_out(bp, CD180_CCR, CCR_TXEN);        /* Enable transmitter     */
273
                rc_out(bp, CD180_IER, IER_TXRDY);       /* Enable tx empty intr   */
274
                msleep(50);
275
                irqs = probe_irq_off(irqs);
276
                val1 = rc_in(bp, RC_BSR);               /* Get Board Status reg   */
277
                val2 = rc_in(bp, RC_ACK_TINT);          /* ACK interrupt          */
278
                rc_init_CD180(bp);                      /* Reset CD180 again      */
279
 
280
                if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX)))  {
281
                        printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not "
282
                                        "found.\n", board_No(bp), bp->base);
283
                        goto out_release;
284
                }
285
        }
286
 
287
        if (irqs <= 0)  {
288
                printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board "
289
                                "at 0x%03x.\n", board_No(bp), bp->base);
290
                goto out_release;
291
        }
292
        bp->irq = irqs;
293
        bp->flags |= RC_BOARD_PRESENT;
294
 
295
        printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at "
296
                         "0x%03x, IRQ %d.\n",
297
               board_No(bp),
298
               (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A',   /* Board revision */
299
               bp->base, bp->irq);
300
 
301
        return 0;
302
out_release:
303
        rc_release_io_range(bp);
304
        return 1;
305
}
306
 
307
/*
308
 *
309
 *  Interrupt processing routines.
310
 *
311
 */
312
 
313
static inline void rc_mark_event(struct riscom_port * port, int event)
314
{
315
        set_bit(event, &port->event);
316
        schedule_work(&port->tqueue);
317
}
318
 
319
static inline struct riscom_port * rc_get_port(struct riscom_board const * bp,
320
                                               unsigned char const * what)
321
{
322
        unsigned char channel;
323
        struct riscom_port * port;
324
 
325
        channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
326
        if (channel < CD180_NCH)  {
327
                port = &rc_port[board_No(bp) * RC_NPORT + channel];
328
                if (port->flags & ASYNC_INITIALIZED)  {
329
                        return port;
330
                }
331
        }
332
        printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
333
               board_No(bp), what, channel);
334
        return NULL;
335
}
336
 
337
static inline void rc_receive_exc(struct riscom_board const * bp)
338
{
339
        struct riscom_port *port;
340
        struct tty_struct *tty;
341
        unsigned char status;
342
        unsigned char ch, flag;
343
 
344
        if (!(port = rc_get_port(bp, "Receive")))
345
                return;
346
 
347
        tty = port->tty;
348
 
349
#ifdef RC_REPORT_OVERRUN        
350
        status = rc_in(bp, CD180_RCSR);
351
        if (status & RCSR_OE)
352
                port->overrun++;
353
        status &= port->mark_mask;
354
#else   
355
        status = rc_in(bp, CD180_RCSR) & port->mark_mask;
356
#endif  
357
        ch = rc_in(bp, CD180_RDR);
358
        if (!status)  {
359
                return;
360
        }
361
        if (status & RCSR_TOUT)  {
362
                printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
363
                                    "Hardware problems ?\n",
364
                       board_No(bp), port_No(port));
365
                return;
366
 
367
        } else if (status & RCSR_BREAK)  {
368
                printk(KERN_INFO "rc%d: port %d: Handling break...\n",
369
                       board_No(bp), port_No(port));
370
                flag = TTY_BREAK;
371
                if (port->flags & ASYNC_SAK)
372
                        do_SAK(tty);
373
 
374
        } else if (status & RCSR_PE)
375
                flag = TTY_PARITY;
376
 
377
        else if (status & RCSR_FE)
378
                flag = TTY_FRAME;
379
 
380
        else if (status & RCSR_OE)
381
                flag = TTY_OVERRUN;
382
 
383
        else
384
                flag = TTY_NORMAL;
385
 
386
        tty_insert_flip_char(tty, ch, flag);
387
        tty_flip_buffer_push(tty);
388
}
389
 
390
static inline void rc_receive(struct riscom_board const * bp)
391
{
392
        struct riscom_port *port;
393
        struct tty_struct *tty;
394
        unsigned char count;
395
 
396
        if (!(port = rc_get_port(bp, "Receive")))
397
                return;
398
 
399
        tty = port->tty;
400
 
401
        count = rc_in(bp, CD180_RDCR);
402
 
403
#ifdef RC_REPORT_FIFO
404
        port->hits[count > 8 ? 9 : count]++;
405
#endif  
406
 
407
        while (count--)  {
408
                if (tty_buffer_request_room(tty, 1) == 0)  {
409
                        printk(KERN_WARNING "rc%d: port %d: Working around "
410
                                            "flip buffer overflow.\n",
411
                               board_No(bp), port_No(port));
412
                        break;
413
                }
414
                tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL);
415
        }
416
        tty_flip_buffer_push(tty);
417
}
418
 
419
static inline void rc_transmit(struct riscom_board const * bp)
420
{
421
        struct riscom_port *port;
422
        struct tty_struct *tty;
423
        unsigned char count;
424
 
425
 
426
        if (!(port = rc_get_port(bp, "Transmit")))
427
                return;
428
 
429
        tty = port->tty;
430
 
431
        if (port->IER & IER_TXEMPTY)  {
432
                /* FIFO drained */
433
                rc_out(bp, CD180_CAR, port_No(port));
434
                port->IER &= ~IER_TXEMPTY;
435
                rc_out(bp, CD180_IER, port->IER);
436
                return;
437
        }
438
 
439
        if ((port->xmit_cnt <= 0 && !port->break_length)
440
            || tty->stopped || tty->hw_stopped)  {
441
                rc_out(bp, CD180_CAR, port_No(port));
442
                port->IER &= ~IER_TXRDY;
443
                rc_out(bp, CD180_IER, port->IER);
444
                return;
445
        }
446
 
447
        if (port->break_length)  {
448
                if (port->break_length > 0)  {
449
                        if (port->COR2 & COR2_ETC)  {
450
                                rc_out(bp, CD180_TDR, CD180_C_ESC);
451
                                rc_out(bp, CD180_TDR, CD180_C_SBRK);
452
                                port->COR2 &= ~COR2_ETC;
453
                        }
454
                        count = min_t(int, port->break_length, 0xff);
455
                        rc_out(bp, CD180_TDR, CD180_C_ESC);
456
                        rc_out(bp, CD180_TDR, CD180_C_DELAY);
457
                        rc_out(bp, CD180_TDR, count);
458
                        if (!(port->break_length -= count))
459
                                port->break_length--;
460
                } else  {
461
                        rc_out(bp, CD180_TDR, CD180_C_ESC);
462
                        rc_out(bp, CD180_TDR, CD180_C_EBRK);
463
                        rc_out(bp, CD180_COR2, port->COR2);
464
                        rc_wait_CCR(bp);
465
                        rc_out(bp, CD180_CCR, CCR_CORCHG2);
466
                        port->break_length = 0;
467
                }
468
                return;
469
        }
470
 
471
        count = CD180_NFIFO;
472
        do {
473
                rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]);
474
                port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
475
                if (--port->xmit_cnt <= 0)
476
                        break;
477
        } while (--count > 0);
478
 
479
        if (port->xmit_cnt <= 0)  {
480
                rc_out(bp, CD180_CAR, port_No(port));
481
                port->IER &= ~IER_TXRDY;
482
                rc_out(bp, CD180_IER, port->IER);
483
        }
484
        if (port->xmit_cnt <= port->wakeup_chars)
485
                rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
486
}
487
 
488
static inline void rc_check_modem(struct riscom_board const * bp)
489
{
490
        struct riscom_port *port;
491
        struct tty_struct *tty;
492
        unsigned char mcr;
493
 
494
        if (!(port = rc_get_port(bp, "Modem")))
495
                return;
496
 
497
        tty = port->tty;
498
 
499
        mcr = rc_in(bp, CD180_MCR);
500
        if (mcr & MCR_CDCHG)  {
501
                if (rc_in(bp, CD180_MSVR) & MSVR_CD)
502
                        wake_up_interruptible(&port->open_wait);
503
                else
504
                        schedule_work(&port->tqueue_hangup);
505
        }
506
 
507
#ifdef RISCOM_BRAIN_DAMAGED_CTS
508
        if (mcr & MCR_CTSCHG)  {
509
                if (rc_in(bp, CD180_MSVR) & MSVR_CTS)  {
510
                        tty->hw_stopped = 0;
511
                        port->IER |= IER_TXRDY;
512
                        if (port->xmit_cnt <= port->wakeup_chars)
513
                                rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
514
                } else  {
515
                        tty->hw_stopped = 1;
516
                        port->IER &= ~IER_TXRDY;
517
                }
518
                rc_out(bp, CD180_IER, port->IER);
519
        }
520
        if (mcr & MCR_DSRCHG)  {
521
                if (rc_in(bp, CD180_MSVR) & MSVR_DSR)  {
522
                        tty->hw_stopped = 0;
523
                        port->IER |= IER_TXRDY;
524
                        if (port->xmit_cnt <= port->wakeup_chars)
525
                                rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
526
                } else  {
527
                        tty->hw_stopped = 1;
528
                        port->IER &= ~IER_TXRDY;
529
                }
530
                rc_out(bp, CD180_IER, port->IER);
531
        }
532
#endif /* RISCOM_BRAIN_DAMAGED_CTS */
533
 
534
        /* Clear change bits */
535
        rc_out(bp, CD180_MCR, 0);
536
}
537
 
538
/* The main interrupt processing routine */
539
static irqreturn_t rc_interrupt(int dummy, void * dev_id)
540
{
541
        unsigned char status;
542
        unsigned char ack;
543
        struct riscom_board *bp = dev_id;
544
        unsigned long loop = 0;
545
        int handled = 0;
546
 
547
        if (!(bp->flags & RC_BOARD_ACTIVE))
548
                return IRQ_NONE;
549
 
550
        while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) &
551
                                 (RC_BSR_TOUT | RC_BSR_TINT |
552
                                  RC_BSR_MINT | RC_BSR_RINT))) {
553
                handled = 1;
554
                if (status & RC_BSR_TOUT)
555
                        printk(KERN_WARNING "rc%d: Got timeout. Hardware "
556
                                            "error?\n", board_No(bp));
557
 
558
                else if (status & RC_BSR_RINT) {
559
                        ack = rc_in(bp, RC_ACK_RINT);
560
 
561
                        if (ack == (RC_ID | GIVR_IT_RCV))
562
                                rc_receive(bp);
563
                        else if (ack == (RC_ID | GIVR_IT_REXC))
564
                                rc_receive_exc(bp);
565
                        else
566
                                printk(KERN_WARNING "rc%d: Bad receive ack "
567
                                                    "0x%02x.\n",
568
                                       board_No(bp), ack);
569
 
570
                } else if (status & RC_BSR_TINT) {
571
                        ack = rc_in(bp, RC_ACK_TINT);
572
 
573
                        if (ack == (RC_ID | GIVR_IT_TX))
574
                                rc_transmit(bp);
575
                        else
576
                                printk(KERN_WARNING "rc%d: Bad transmit ack "
577
                                                    "0x%02x.\n",
578
                                       board_No(bp), ack);
579
 
580
                } else /* if (status & RC_BSR_MINT) */ {
581
                        ack = rc_in(bp, RC_ACK_MINT);
582
 
583
                        if (ack == (RC_ID | GIVR_IT_MODEM))
584
                                rc_check_modem(bp);
585
                        else
586
                                printk(KERN_WARNING "rc%d: Bad modem ack "
587
                                                    "0x%02x.\n",
588
                                       board_No(bp), ack);
589
 
590
                }
591
 
592
                rc_out(bp, CD180_EOIR, 0);   /* Mark end of interrupt */
593
                rc_out(bp, RC_CTOUT, 0);     /* Clear timeout flag    */
594
        }
595
        return IRQ_RETVAL(handled);
596
}
597
 
598
/*
599
 *  Routines for open & close processing.
600
 */
601
 
602
/* Called with disabled interrupts */
603
static int rc_setup_board(struct riscom_board * bp)
604
{
605
        int error;
606
 
607
        if (bp->flags & RC_BOARD_ACTIVE)
608
                return 0;
609
 
610
        error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED,
611
                            "RISCom/8", bp);
612
        if (error)
613
                return error;
614
 
615
        rc_out(bp, RC_CTOUT, 0);                 /* Just in case         */
616
        bp->DTR = ~0;
617
        rc_out(bp, RC_DTR, bp->DTR);            /* Drop DTR on all ports */
618
 
619
        bp->flags |= RC_BOARD_ACTIVE;
620
 
621
        return 0;
622
}
623
 
624
/* Called with disabled interrupts */
625
static void rc_shutdown_board(struct riscom_board *bp)
626
{
627
        if (!(bp->flags & RC_BOARD_ACTIVE))
628
                return;
629
 
630
        bp->flags &= ~RC_BOARD_ACTIVE;
631
 
632
        free_irq(bp->irq, NULL);
633
 
634
        bp->DTR = ~0;
635
        rc_out(bp, RC_DTR, bp->DTR);           /* Drop DTR on all ports */
636
 
637
}
638
 
639
/*
640
 * Setting up port characteristics.
641
 * Must be called with disabled interrupts
642
 */
643
static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
644
{
645
        struct tty_struct *tty;
646
        unsigned long baud;
647
        long tmp;
648
        unsigned char cor1 = 0, cor3 = 0;
649
        unsigned char mcor1 = 0, mcor2 = 0;
650
 
651
        if (!(tty = port->tty) || !tty->termios)
652
                return;
653
 
654
        port->IER  = 0;
655
        port->COR2 = 0;
656
        port->MSVR = MSVR_RTS;
657
 
658
        baud = tty_get_baud_rate(tty);
659
 
660
        /* Select port on the board */
661
        rc_out(bp, CD180_CAR, port_No(port));
662
 
663
        if (!baud)  {
664
                /* Drop DTR & exit */
665
                bp->DTR |= (1u << port_No(port));
666
                rc_out(bp, RC_DTR, bp->DTR);
667
                return;
668
        } else  {
669
                /* Set DTR on */
670
                bp->DTR &= ~(1u << port_No(port));
671
                rc_out(bp, RC_DTR, bp->DTR);
672
        }
673
 
674
        /*
675
         * Now we must calculate some speed depended things
676
         */
677
 
678
        /* Set baud rate for port */
679
        tmp = (((RC_OSCFREQ + baud/2) / baud +
680
                CD180_TPC/2) / CD180_TPC);
681
 
682
        rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
683
        rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
684
        rc_out(bp, CD180_RBPRL, tmp & 0xff);
685
        rc_out(bp, CD180_TBPRL, tmp & 0xff);
686
 
687
        baud = (baud + 5) / 10;   /* Estimated CPS */
688
 
689
        /* Two timer ticks seems enough to wakeup something like SLIP driver */
690
        tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
691
        port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
692
                                              SERIAL_XMIT_SIZE - 1 : tmp);
693
 
694
        /* Receiver timeout will be transmission time for 1.5 chars */
695
        tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud;
696
        tmp = (tmp > 0xff) ? 0xff : tmp;
697
        rc_out(bp, CD180_RTPR, tmp);
698
 
699
        switch (C_CSIZE(tty))  {
700
         case CS5:
701
                cor1 |= COR1_5BITS;
702
                break;
703
         case CS6:
704
                cor1 |= COR1_6BITS;
705
                break;
706
         case CS7:
707
                cor1 |= COR1_7BITS;
708
                break;
709
         case CS8:
710
                cor1 |= COR1_8BITS;
711
                break;
712
        }
713
 
714
        if (C_CSTOPB(tty))
715
                cor1 |= COR1_2SB;
716
 
717
        cor1 |= COR1_IGNORE;
718
        if (C_PARENB(tty))  {
719
                cor1 |= COR1_NORMPAR;
720
                if (C_PARODD(tty))
721
                        cor1 |= COR1_ODDP;
722
                if (I_INPCK(tty))
723
                        cor1 &= ~COR1_IGNORE;
724
        }
725
        /* Set marking of some errors */
726
        port->mark_mask = RCSR_OE | RCSR_TOUT;
727
        if (I_INPCK(tty))
728
                port->mark_mask |= RCSR_FE | RCSR_PE;
729
        if (I_BRKINT(tty) || I_PARMRK(tty))
730
                port->mark_mask |= RCSR_BREAK;
731
        if (I_IGNPAR(tty))
732
                port->mark_mask &= ~(RCSR_FE | RCSR_PE);
733
        if (I_IGNBRK(tty))  {
734
                port->mark_mask &= ~RCSR_BREAK;
735
                if (I_IGNPAR(tty))
736
                        /* Real raw mode. Ignore all */
737
                        port->mark_mask &= ~RCSR_OE;
738
        }
739
        /* Enable Hardware Flow Control */
740
        if (C_CRTSCTS(tty))  {
741
#ifdef RISCOM_BRAIN_DAMAGED_CTS
742
                port->IER |= IER_DSR | IER_CTS;
743
                mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
744
                mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
745
                tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
746
#else
747
                port->COR2 |= COR2_CTSAE;
748
#endif
749
        }
750
        /* Enable Software Flow Control. FIXME: I'm not sure about this */
751
        /* Some people reported that it works, but I still doubt */
752
        if (I_IXON(tty))  {
753
                port->COR2 |= COR2_TXIBE;
754
                cor3 |= (COR3_FCT | COR3_SCDE);
755
                if (I_IXANY(tty))
756
                        port->COR2 |= COR2_IXM;
757
                rc_out(bp, CD180_SCHR1, START_CHAR(tty));
758
                rc_out(bp, CD180_SCHR2, STOP_CHAR(tty));
759
                rc_out(bp, CD180_SCHR3, START_CHAR(tty));
760
                rc_out(bp, CD180_SCHR4, STOP_CHAR(tty));
761
        }
762
        if (!C_CLOCAL(tty))  {
763
                /* Enable CD check */
764
                port->IER |= IER_CD;
765
                mcor1 |= MCOR1_CDZD;
766
                mcor2 |= MCOR2_CDOD;
767
        }
768
 
769
        if (C_CREAD(tty))
770
                /* Enable receiver */
771
                port->IER |= IER_RXD;
772
 
773
        /* Set input FIFO size (1-8 bytes) */
774
        cor3 |= RISCOM_RXFIFO;
775
        /* Setting up CD180 channel registers */
776
        rc_out(bp, CD180_COR1, cor1);
777
        rc_out(bp, CD180_COR2, port->COR2);
778
        rc_out(bp, CD180_COR3, cor3);
779
        /* Make CD180 know about registers change */
780
        rc_wait_CCR(bp);
781
        rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
782
        /* Setting up modem option registers */
783
        rc_out(bp, CD180_MCOR1, mcor1);
784
        rc_out(bp, CD180_MCOR2, mcor2);
785
        /* Enable CD180 transmitter & receiver */
786
        rc_wait_CCR(bp);
787
        rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN);
788
        /* Enable interrupts */
789
        rc_out(bp, CD180_IER, port->IER);
790
        /* And finally set RTS on */
791
        rc_out(bp, CD180_MSVR, port->MSVR);
792
}
793
 
794
/* Must be called with interrupts enabled */
795
static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
796
{
797
        unsigned long flags;
798
 
799
        if (port->flags & ASYNC_INITIALIZED)
800
                return 0;
801
 
802
        if (!port->xmit_buf) {
803
                /* We may sleep in get_zeroed_page() */
804
                unsigned long tmp;
805
 
806
                if (!(tmp = get_zeroed_page(GFP_KERNEL)))
807
                        return -ENOMEM;
808
 
809
                if (port->xmit_buf) {
810
                        free_page(tmp);
811
                        return -ERESTARTSYS;
812
                }
813
                port->xmit_buf = (unsigned char *) tmp;
814
        }
815
 
816
        save_flags(flags); cli();
817
 
818
        if (port->tty)
819
                clear_bit(TTY_IO_ERROR, &port->tty->flags);
820
 
821
        if (port->count == 1)
822
                bp->count++;
823
 
824
        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
825
        rc_change_speed(bp, port);
826
        port->flags |= ASYNC_INITIALIZED;
827
 
828
        restore_flags(flags);
829
        return 0;
830
}
831
 
832
/* Must be called with interrupts disabled */
833
static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
834
{
835
        struct tty_struct *tty;
836
 
837
        if (!(port->flags & ASYNC_INITIALIZED))
838
                return;
839
 
840
#ifdef RC_REPORT_OVERRUN
841
        printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
842
               board_No(bp), port_No(port), port->overrun);
843
#endif  
844
#ifdef RC_REPORT_FIFO
845
        {
846
                int i;
847
 
848
                printk(KERN_INFO "rc%d: port %d: FIFO hits [ ",
849
                       board_No(bp), port_No(port));
850
                for (i = 0; i < 10; i++)  {
851
                        printk("%ld ", port->hits[i]);
852
                }
853
                printk("].\n");
854
        }
855
#endif  
856
        if (port->xmit_buf)  {
857
                free_page((unsigned long) port->xmit_buf);
858
                port->xmit_buf = NULL;
859
        }
860
 
861
        if (!(tty = port->tty) || C_HUPCL(tty))  {
862
                /* Drop DTR */
863
                bp->DTR |= (1u << port_No(port));
864
                rc_out(bp, RC_DTR, bp->DTR);
865
        }
866
 
867
        /* Select port */
868
        rc_out(bp, CD180_CAR, port_No(port));
869
        /* Reset port */
870
        rc_wait_CCR(bp);
871
        rc_out(bp, CD180_CCR, CCR_SOFTRESET);
872
        /* Disable all interrupts from this port */
873
        port->IER = 0;
874
        rc_out(bp, CD180_IER, port->IER);
875
 
876
        if (tty)
877
                set_bit(TTY_IO_ERROR, &tty->flags);
878
        port->flags &= ~ASYNC_INITIALIZED;
879
 
880
        if (--bp->count < 0)  {
881
                printk(KERN_INFO "rc%d: rc_shutdown_port: "
882
                                 "bad board count: %d\n",
883
                       board_No(bp), bp->count);
884
                bp->count = 0;
885
        }
886
 
887
        /*
888
         * If this is the last opened port on the board
889
         * shutdown whole board
890
         */
891
        if (!bp->count)
892
                rc_shutdown_board(bp);
893
}
894
 
895
 
896
static int block_til_ready(struct tty_struct *tty, struct file * filp,
897
                           struct riscom_port *port)
898
{
899
        DECLARE_WAITQUEUE(wait, current);
900
        struct riscom_board *bp = port_Board(port);
901
        int    retval;
902
        int    do_clocal = 0;
903
        int    CD;
904
 
905
        /*
906
         * If the device is in the middle of being closed, then block
907
         * until it's done, and then try again.
908
         */
909
        if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
910
                interruptible_sleep_on(&port->close_wait);
911
                if (port->flags & ASYNC_HUP_NOTIFY)
912
                        return -EAGAIN;
913
                else
914
                        return -ERESTARTSYS;
915
        }
916
 
917
        /*
918
         * If non-blocking mode is set, or the port is not enabled,
919
         * then make the check up front and then exit.
920
         */
921
        if ((filp->f_flags & O_NONBLOCK) ||
922
            (tty->flags & (1 << TTY_IO_ERROR))) {
923
                port->flags |= ASYNC_NORMAL_ACTIVE;
924
                return 0;
925
        }
926
 
927
        if (C_CLOCAL(tty))
928
                do_clocal = 1;
929
 
930
        /*
931
         * Block waiting for the carrier detect and the line to become
932
         * free (i.e., not in use by the callout).  While we are in
933
         * this loop, info->count is dropped by one, so that
934
         * rs_close() knows when to free things.  We restore it upon
935
         * exit, either normal or abnormal.
936
         */
937
        retval = 0;
938
        add_wait_queue(&port->open_wait, &wait);
939
        cli();
940
        if (!tty_hung_up_p(filp))
941
                port->count--;
942
        sti();
943
        port->blocked_open++;
944
        while (1) {
945
                cli();
946
                rc_out(bp, CD180_CAR, port_No(port));
947
                CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
948
                rc_out(bp, CD180_MSVR, MSVR_RTS);
949
                bp->DTR &= ~(1u << port_No(port));
950
                rc_out(bp, RC_DTR, bp->DTR);
951
                sti();
952
                set_current_state(TASK_INTERRUPTIBLE);
953
                if (tty_hung_up_p(filp) ||
954
                    !(port->flags & ASYNC_INITIALIZED)) {
955
                        if (port->flags & ASYNC_HUP_NOTIFY)
956
                                retval = -EAGAIN;
957
                        else
958
                                retval = -ERESTARTSYS;
959
                        break;
960
                }
961
                if (!(port->flags & ASYNC_CLOSING) &&
962
                    (do_clocal || CD))
963
                        break;
964
                if (signal_pending(current)) {
965
                        retval = -ERESTARTSYS;
966
                        break;
967
                }
968
                schedule();
969
        }
970
        __set_current_state(TASK_RUNNING);
971
        remove_wait_queue(&port->open_wait, &wait);
972
        if (!tty_hung_up_p(filp))
973
                port->count++;
974
        port->blocked_open--;
975
        if (retval)
976
                return retval;
977
 
978
        port->flags |= ASYNC_NORMAL_ACTIVE;
979
        return 0;
980
}
981
 
982
static int rc_open(struct tty_struct * tty, struct file * filp)
983
{
984
        int board;
985
        int error;
986
        struct riscom_port * port;
987
        struct riscom_board * bp;
988
 
989
        board = RC_BOARD(tty->index);
990
        if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
991
                return -ENODEV;
992
 
993
        bp = &rc_board[board];
994
        port = rc_port + board * RC_NPORT + RC_PORT(tty->index);
995
        if (rc_paranoia_check(port, tty->name, "rc_open"))
996
                return -ENODEV;
997
 
998
        if ((error = rc_setup_board(bp)))
999
                return error;
1000
 
1001
        port->count++;
1002
        tty->driver_data = port;
1003
        port->tty = tty;
1004
 
1005
        if ((error = rc_setup_port(bp, port)))
1006
                return error;
1007
 
1008
        if ((error = block_til_ready(tty, filp, port)))
1009
                return error;
1010
 
1011
        return 0;
1012
}
1013
 
1014
static void rc_close(struct tty_struct * tty, struct file * filp)
1015
{
1016
        struct riscom_port *port = (struct riscom_port *) tty->driver_data;
1017
        struct riscom_board *bp;
1018
        unsigned long flags;
1019
        unsigned long timeout;
1020
 
1021
        if (!port || rc_paranoia_check(port, tty->name, "close"))
1022
                return;
1023
 
1024
        save_flags(flags); cli();
1025
        if (tty_hung_up_p(filp))
1026
                goto out;
1027
 
1028
        bp = port_Board(port);
1029
        if ((tty->count == 1) && (port->count != 1))  {
1030
                printk(KERN_INFO "rc%d: rc_close: bad port count;"
1031
                       " tty->count is 1, port count is %d\n",
1032
                       board_No(bp), port->count);
1033
                port->count = 1;
1034
        }
1035
        if (--port->count < 0)  {
1036
                printk(KERN_INFO "rc%d: rc_close: bad port count "
1037
                                 "for tty%d: %d\n",
1038
                       board_No(bp), port_No(port), port->count);
1039
                port->count = 0;
1040
        }
1041
        if (port->count)
1042
                goto out;
1043
        port->flags |= ASYNC_CLOSING;
1044
        /*
1045
         * Now we wait for the transmit buffer to clear; and we notify
1046
         * the line discipline to only process XON/XOFF characters.
1047
         */
1048
        tty->closing = 1;
1049
        if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1050
                tty_wait_until_sent(tty, port->closing_wait);
1051
        /*
1052
         * At this point we stop accepting input.  To do this, we
1053
         * disable the receive line status interrupts, and tell the
1054
         * interrupt driver to stop checking the data ready bit in the
1055
         * line status register.
1056
         */
1057
        port->IER &= ~IER_RXD;
1058
        if (port->flags & ASYNC_INITIALIZED) {
1059
                port->IER &= ~IER_TXRDY;
1060
                port->IER |= IER_TXEMPTY;
1061
                rc_out(bp, CD180_CAR, port_No(port));
1062
                rc_out(bp, CD180_IER, port->IER);
1063
                /*
1064
                 * Before we drop DTR, make sure the UART transmitter
1065
                 * has completely drained; this is especially
1066
                 * important if there is a transmit FIFO!
1067
                 */
1068
                timeout = jiffies+HZ;
1069
                while(port->IER & IER_TXEMPTY)  {
1070
                        msleep_interruptible(jiffies_to_msecs(port->timeout));
1071
                        if (time_after(jiffies, timeout))
1072
                                break;
1073
                }
1074
        }
1075
        rc_shutdown_port(bp, port);
1076
        if (tty->driver->flush_buffer)
1077
                tty->driver->flush_buffer(tty);
1078
        tty_ldisc_flush(tty);
1079
 
1080
        tty->closing = 0;
1081
        port->event = 0;
1082
        port->tty = NULL;
1083
        if (port->blocked_open) {
1084
                if (port->close_delay) {
1085
                        msleep_interruptible(jiffies_to_msecs(port->close_delay));
1086
                }
1087
                wake_up_interruptible(&port->open_wait);
1088
        }
1089
        port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1090
        wake_up_interruptible(&port->close_wait);
1091
out:    restore_flags(flags);
1092
}
1093
 
1094
static int rc_write(struct tty_struct * tty,
1095
                    const unsigned char *buf, int count)
1096
{
1097
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1098
        struct riscom_board *bp;
1099
        int c, total = 0;
1100
        unsigned long flags;
1101
 
1102
        if (rc_paranoia_check(port, tty->name, "rc_write"))
1103
                return 0;
1104
 
1105
        bp = port_Board(port);
1106
 
1107
        if (!tty || !port->xmit_buf)
1108
                return 0;
1109
 
1110
        save_flags(flags);
1111
        while (1) {
1112
                cli();
1113
                c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1114
                                          SERIAL_XMIT_SIZE - port->xmit_head));
1115
                if (c <= 0) {
1116
                        restore_flags(flags);
1117
                        break;
1118
                }
1119
 
1120
                memcpy(port->xmit_buf + port->xmit_head, buf, c);
1121
                port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1122
                port->xmit_cnt += c;
1123
                restore_flags(flags);
1124
 
1125
                buf += c;
1126
                count -= c;
1127
                total += c;
1128
        }
1129
 
1130
        cli();
1131
        if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1132
            !(port->IER & IER_TXRDY)) {
1133
                port->IER |= IER_TXRDY;
1134
                rc_out(bp, CD180_CAR, port_No(port));
1135
                rc_out(bp, CD180_IER, port->IER);
1136
        }
1137
        restore_flags(flags);
1138
 
1139
        return total;
1140
}
1141
 
1142
static void rc_put_char(struct tty_struct * tty, unsigned char ch)
1143
{
1144
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1145
        unsigned long flags;
1146
 
1147
        if (rc_paranoia_check(port, tty->name, "rc_put_char"))
1148
                return;
1149
 
1150
        if (!tty || !port->xmit_buf)
1151
                return;
1152
 
1153
        save_flags(flags); cli();
1154
 
1155
        if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1156
                goto out;
1157
 
1158
        port->xmit_buf[port->xmit_head++] = ch;
1159
        port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1160
        port->xmit_cnt++;
1161
out:    restore_flags(flags);
1162
}
1163
 
1164
static void rc_flush_chars(struct tty_struct * tty)
1165
{
1166
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1167
        unsigned long flags;
1168
 
1169
        if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
1170
                return;
1171
 
1172
        if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1173
            !port->xmit_buf)
1174
                return;
1175
 
1176
        save_flags(flags); cli();
1177
        port->IER |= IER_TXRDY;
1178
        rc_out(port_Board(port), CD180_CAR, port_No(port));
1179
        rc_out(port_Board(port), CD180_IER, port->IER);
1180
        restore_flags(flags);
1181
}
1182
 
1183
static int rc_write_room(struct tty_struct * tty)
1184
{
1185
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1186
        int     ret;
1187
 
1188
        if (rc_paranoia_check(port, tty->name, "rc_write_room"))
1189
                return 0;
1190
 
1191
        ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1192
        if (ret < 0)
1193
                ret = 0;
1194
        return ret;
1195
}
1196
 
1197
static int rc_chars_in_buffer(struct tty_struct *tty)
1198
{
1199
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1200
 
1201
        if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer"))
1202
                return 0;
1203
 
1204
        return port->xmit_cnt;
1205
}
1206
 
1207
static void rc_flush_buffer(struct tty_struct *tty)
1208
{
1209
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1210
        unsigned long flags;
1211
 
1212
        if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
1213
                return;
1214
 
1215
        save_flags(flags); cli();
1216
        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1217
        restore_flags(flags);
1218
 
1219
        tty_wakeup(tty);
1220
}
1221
 
1222
static int rc_tiocmget(struct tty_struct *tty, struct file *file)
1223
{
1224
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1225
        struct riscom_board * bp;
1226
        unsigned char status;
1227
        unsigned int result;
1228
        unsigned long flags;
1229
 
1230
        if (rc_paranoia_check(port, tty->name, __FUNCTION__))
1231
                return -ENODEV;
1232
 
1233
        bp = port_Board(port);
1234
        save_flags(flags); cli();
1235
        rc_out(bp, CD180_CAR, port_No(port));
1236
        status = rc_in(bp, CD180_MSVR);
1237
        result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
1238
        restore_flags(flags);
1239
        result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
1240
                | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1241
                | ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1242
                | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
1243
                | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1244
        return result;
1245
}
1246
 
1247
static int rc_tiocmset(struct tty_struct *tty, struct file *file,
1248
                       unsigned int set, unsigned int clear)
1249
{
1250
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1251
        unsigned long flags;
1252
        struct riscom_board *bp;
1253
 
1254
        if (rc_paranoia_check(port, tty->name, __FUNCTION__))
1255
                return -ENODEV;
1256
 
1257
        bp = port_Board(port);
1258
 
1259
        save_flags(flags); cli();
1260
        if (set & TIOCM_RTS)
1261
                port->MSVR |= MSVR_RTS;
1262
        if (set & TIOCM_DTR)
1263
                bp->DTR &= ~(1u << port_No(port));
1264
 
1265
        if (clear & TIOCM_RTS)
1266
                port->MSVR &= ~MSVR_RTS;
1267
        if (clear & TIOCM_DTR)
1268
                bp->DTR |= (1u << port_No(port));
1269
 
1270
        rc_out(bp, CD180_CAR, port_No(port));
1271
        rc_out(bp, CD180_MSVR, port->MSVR);
1272
        rc_out(bp, RC_DTR, bp->DTR);
1273
        restore_flags(flags);
1274
        return 0;
1275
}
1276
 
1277
static inline void rc_send_break(struct riscom_port * port, unsigned long length)
1278
{
1279
        struct riscom_board *bp = port_Board(port);
1280
        unsigned long flags;
1281
 
1282
        save_flags(flags); cli();
1283
        port->break_length = RISCOM_TPS / HZ * length;
1284
        port->COR2 |= COR2_ETC;
1285
        port->IER  |= IER_TXRDY;
1286
        rc_out(bp, CD180_CAR, port_No(port));
1287
        rc_out(bp, CD180_COR2, port->COR2);
1288
        rc_out(bp, CD180_IER, port->IER);
1289
        rc_wait_CCR(bp);
1290
        rc_out(bp, CD180_CCR, CCR_CORCHG2);
1291
        rc_wait_CCR(bp);
1292
        restore_flags(flags);
1293
}
1294
 
1295
static inline int rc_set_serial_info(struct riscom_port * port,
1296
                                     struct serial_struct __user * newinfo)
1297
{
1298
        struct serial_struct tmp;
1299
        struct riscom_board *bp = port_Board(port);
1300
        int change_speed;
1301
        unsigned long flags;
1302
 
1303
        if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1304
                return -EFAULT;
1305
 
1306
#if 0   
1307
        if ((tmp.irq != bp->irq) ||
1308
            (tmp.port != bp->base) ||
1309
            (tmp.type != PORT_CIRRUS) ||
1310
            (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1311
            (tmp.custom_divisor != 0) ||
1312
            (tmp.xmit_fifo_size != CD180_NFIFO) ||
1313
            (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1314
                return -EINVAL;
1315
#endif  
1316
 
1317
        change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1318
                        (tmp.flags & ASYNC_SPD_MASK));
1319
 
1320
        if (!capable(CAP_SYS_ADMIN)) {
1321
                if ((tmp.close_delay != port->close_delay) ||
1322
                    (tmp.closing_wait != port->closing_wait) ||
1323
                    ((tmp.flags & ~ASYNC_USR_MASK) !=
1324
                     (port->flags & ~ASYNC_USR_MASK)))
1325
                        return -EPERM;
1326
                port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1327
                               (tmp.flags & ASYNC_USR_MASK));
1328
        } else  {
1329
                port->flags = ((port->flags & ~ASYNC_FLAGS) |
1330
                               (tmp.flags & ASYNC_FLAGS));
1331
                port->close_delay = tmp.close_delay;
1332
                port->closing_wait = tmp.closing_wait;
1333
        }
1334
        if (change_speed)  {
1335
                save_flags(flags); cli();
1336
                rc_change_speed(bp, port);
1337
                restore_flags(flags);
1338
        }
1339
        return 0;
1340
}
1341
 
1342
static inline int rc_get_serial_info(struct riscom_port * port,
1343
                                     struct serial_struct __user *retinfo)
1344
{
1345
        struct serial_struct tmp;
1346
        struct riscom_board *bp = port_Board(port);
1347
 
1348
        memset(&tmp, 0, sizeof(tmp));
1349
        tmp.type = PORT_CIRRUS;
1350
        tmp.line = port - rc_port;
1351
        tmp.port = bp->base;
1352
        tmp.irq  = bp->irq;
1353
        tmp.flags = port->flags;
1354
        tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
1355
        tmp.close_delay = port->close_delay * HZ/100;
1356
        tmp.closing_wait = port->closing_wait * HZ/100;
1357
        tmp.xmit_fifo_size = CD180_NFIFO;
1358
        return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0;
1359
}
1360
 
1361
static int rc_ioctl(struct tty_struct * tty, struct file * filp,
1362
                    unsigned int cmd, unsigned long arg)
1363
 
1364
{
1365
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1366
        void __user *argp = (void __user *)arg;
1367
        int retval;
1368
 
1369
        if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
1370
                return -ENODEV;
1371
 
1372
        switch (cmd) {
1373
         case TCSBRK:   /* SVID version: non-zero arg --> no break */
1374
                retval = tty_check_change(tty);
1375
                if (retval)
1376
                        return retval;
1377
                tty_wait_until_sent(tty, 0);
1378
                if (!arg)
1379
                        rc_send_break(port, HZ/4);      /* 1/4 second */
1380
                break;
1381
         case TCSBRKP:  /* support for POSIX tcsendbreak() */
1382
                retval = tty_check_change(tty);
1383
                if (retval)
1384
                        return retval;
1385
                tty_wait_until_sent(tty, 0);
1386
                rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
1387
                break;
1388
         case TIOCGSOFTCAR:
1389
                return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned __user *)argp);
1390
         case TIOCSSOFTCAR:
1391
                if (get_user(arg,(unsigned __user *) argp))
1392
                        return -EFAULT;
1393
                tty->termios->c_cflag =
1394
                        ((tty->termios->c_cflag & ~CLOCAL) |
1395
                        (arg ? CLOCAL : 0));
1396
                break;
1397
         case TIOCGSERIAL:
1398
                return rc_get_serial_info(port, argp);
1399
         case TIOCSSERIAL:
1400
                return rc_set_serial_info(port, argp);
1401
         default:
1402
                return -ENOIOCTLCMD;
1403
        }
1404
        return 0;
1405
}
1406
 
1407
static void rc_throttle(struct tty_struct * tty)
1408
{
1409
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1410
        struct riscom_board *bp;
1411
        unsigned long flags;
1412
 
1413
        if (rc_paranoia_check(port, tty->name, "rc_throttle"))
1414
                return;
1415
 
1416
        bp = port_Board(port);
1417
 
1418
        save_flags(flags); cli();
1419
        port->MSVR &= ~MSVR_RTS;
1420
        rc_out(bp, CD180_CAR, port_No(port));
1421
        if (I_IXOFF(tty))  {
1422
                rc_wait_CCR(bp);
1423
                rc_out(bp, CD180_CCR, CCR_SSCH2);
1424
                rc_wait_CCR(bp);
1425
        }
1426
        rc_out(bp, CD180_MSVR, port->MSVR);
1427
        restore_flags(flags);
1428
}
1429
 
1430
static void rc_unthrottle(struct tty_struct * tty)
1431
{
1432
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1433
        struct riscom_board *bp;
1434
        unsigned long flags;
1435
 
1436
        if (rc_paranoia_check(port, tty->name, "rc_unthrottle"))
1437
                return;
1438
 
1439
        bp = port_Board(port);
1440
 
1441
        save_flags(flags); cli();
1442
        port->MSVR |= MSVR_RTS;
1443
        rc_out(bp, CD180_CAR, port_No(port));
1444
        if (I_IXOFF(tty))  {
1445
                rc_wait_CCR(bp);
1446
                rc_out(bp, CD180_CCR, CCR_SSCH1);
1447
                rc_wait_CCR(bp);
1448
        }
1449
        rc_out(bp, CD180_MSVR, port->MSVR);
1450
        restore_flags(flags);
1451
}
1452
 
1453
static void rc_stop(struct tty_struct * tty)
1454
{
1455
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1456
        struct riscom_board *bp;
1457
        unsigned long flags;
1458
 
1459
        if (rc_paranoia_check(port, tty->name, "rc_stop"))
1460
                return;
1461
 
1462
        bp = port_Board(port);
1463
 
1464
        save_flags(flags); cli();
1465
        port->IER &= ~IER_TXRDY;
1466
        rc_out(bp, CD180_CAR, port_No(port));
1467
        rc_out(bp, CD180_IER, port->IER);
1468
        restore_flags(flags);
1469
}
1470
 
1471
static void rc_start(struct tty_struct * tty)
1472
{
1473
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1474
        struct riscom_board *bp;
1475
        unsigned long flags;
1476
 
1477
        if (rc_paranoia_check(port, tty->name, "rc_start"))
1478
                return;
1479
 
1480
        bp = port_Board(port);
1481
 
1482
        save_flags(flags); cli();
1483
        if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY))  {
1484
                port->IER |= IER_TXRDY;
1485
                rc_out(bp, CD180_CAR, port_No(port));
1486
                rc_out(bp, CD180_IER, port->IER);
1487
        }
1488
        restore_flags(flags);
1489
}
1490
 
1491
/*
1492
 * This routine is called from the work queue when the interrupt
1493
 * routine has signalled that a hangup has occurred.  The path of
1494
 * hangup processing is:
1495
 *
1496
 *      serial interrupt routine -> (workqueue) ->
1497
 *      do_rc_hangup() -> tty->hangup() -> rc_hangup()
1498
 *
1499
 */
1500
static void do_rc_hangup(struct work_struct *ugly_api)
1501
{
1502
        struct riscom_port      *port = container_of(ugly_api, struct riscom_port, tqueue_hangup);
1503
        struct tty_struct       *tty;
1504
 
1505
        tty = port->tty;
1506
        if (tty)
1507
                tty_hangup(tty);        /* FIXME: module removal race still here */
1508
}
1509
 
1510
static void rc_hangup(struct tty_struct * tty)
1511
{
1512
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1513
        struct riscom_board *bp;
1514
 
1515
        if (rc_paranoia_check(port, tty->name, "rc_hangup"))
1516
                return;
1517
 
1518
        bp = port_Board(port);
1519
 
1520
        rc_shutdown_port(bp, port);
1521
        port->event = 0;
1522
        port->count = 0;
1523
        port->flags &= ~ASYNC_NORMAL_ACTIVE;
1524
        port->tty = NULL;
1525
        wake_up_interruptible(&port->open_wait);
1526
}
1527
 
1528
static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
1529
{
1530
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1531
        unsigned long flags;
1532
 
1533
        if (rc_paranoia_check(port, tty->name, "rc_set_termios"))
1534
                return;
1535
 
1536
        if (tty->termios->c_cflag == old_termios->c_cflag &&
1537
            tty->termios->c_iflag == old_termios->c_iflag)
1538
                return;
1539
 
1540
        save_flags(flags); cli();
1541
        rc_change_speed(port_Board(port), port);
1542
        restore_flags(flags);
1543
 
1544
        if ((old_termios->c_cflag & CRTSCTS) &&
1545
            !(tty->termios->c_cflag & CRTSCTS)) {
1546
                tty->hw_stopped = 0;
1547
                rc_start(tty);
1548
        }
1549
}
1550
 
1551
static void do_softint(struct work_struct *ugly_api)
1552
{
1553
        struct riscom_port      *port = container_of(ugly_api, struct riscom_port, tqueue);
1554
        struct tty_struct       *tty;
1555
 
1556
        if(!(tty = port->tty))
1557
                return;
1558
 
1559
        if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event))
1560
                tty_wakeup(tty);
1561
}
1562
 
1563
static const struct tty_operations riscom_ops = {
1564
        .open  = rc_open,
1565
        .close = rc_close,
1566
        .write = rc_write,
1567
        .put_char = rc_put_char,
1568
        .flush_chars = rc_flush_chars,
1569
        .write_room = rc_write_room,
1570
        .chars_in_buffer = rc_chars_in_buffer,
1571
        .flush_buffer = rc_flush_buffer,
1572
        .ioctl = rc_ioctl,
1573
        .throttle = rc_throttle,
1574
        .unthrottle = rc_unthrottle,
1575
        .set_termios = rc_set_termios,
1576
        .stop = rc_stop,
1577
        .start = rc_start,
1578
        .hangup = rc_hangup,
1579
        .tiocmget = rc_tiocmget,
1580
        .tiocmset = rc_tiocmset,
1581
};
1582
 
1583
static inline int rc_init_drivers(void)
1584
{
1585
        int error;
1586
        int i;
1587
 
1588
        riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT);
1589
        if (!riscom_driver)
1590
                return -ENOMEM;
1591
 
1592
        riscom_driver->owner = THIS_MODULE;
1593
        riscom_driver->name = "ttyL";
1594
        riscom_driver->major = RISCOM8_NORMAL_MAJOR;
1595
        riscom_driver->type = TTY_DRIVER_TYPE_SERIAL;
1596
        riscom_driver->subtype = SERIAL_TYPE_NORMAL;
1597
        riscom_driver->init_termios = tty_std_termios;
1598
        riscom_driver->init_termios.c_cflag =
1599
                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1600
        riscom_driver->init_termios.c_ispeed = 9600;
1601
        riscom_driver->init_termios.c_ospeed = 9600;
1602
        riscom_driver->flags = TTY_DRIVER_REAL_RAW;
1603
        tty_set_operations(riscom_driver, &riscom_ops);
1604
        if ((error = tty_register_driver(riscom_driver)))  {
1605
                put_tty_driver(riscom_driver);
1606
                printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
1607
                                "error = %d\n",
1608
                       error);
1609
                return 1;
1610
        }
1611
 
1612
        memset(rc_port, 0, sizeof(rc_port));
1613
        for (i = 0; i < RC_NPORT * RC_NBOARD; i++)  {
1614
                rc_port[i].magic = RISCOM8_MAGIC;
1615
                INIT_WORK(&rc_port[i].tqueue, do_softint);
1616
                INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup);
1617
                rc_port[i].close_delay = 50 * HZ/100;
1618
                rc_port[i].closing_wait = 3000 * HZ/100;
1619
                init_waitqueue_head(&rc_port[i].open_wait);
1620
                init_waitqueue_head(&rc_port[i].close_wait);
1621
        }
1622
 
1623
        return 0;
1624
}
1625
 
1626
static void rc_release_drivers(void)
1627
{
1628
        unsigned long flags;
1629
 
1630
        save_flags(flags);
1631
        cli();
1632
        tty_unregister_driver(riscom_driver);
1633
        put_tty_driver(riscom_driver);
1634
        restore_flags(flags);
1635
}
1636
 
1637
#ifndef MODULE
1638
/*
1639
 * Called at boot time.
1640
 *
1641
 * You can specify IO base for up to RC_NBOARD cards,
1642
 * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
1643
 * Note that there will be no probing at default
1644
 * addresses in this case.
1645
 *
1646
 */
1647
static int __init riscom8_setup(char *str)
1648
{
1649
        int ints[RC_NBOARD];
1650
        int i;
1651
 
1652
        str = get_options(str, ARRAY_SIZE(ints), ints);
1653
 
1654
        for (i = 0; i < RC_NBOARD; i++) {
1655
                if (i < ints[0])
1656
                        rc_board[i].base = ints[i+1];
1657
                else
1658
                        rc_board[i].base = 0;
1659
        }
1660
        return 1;
1661
}
1662
 
1663
__setup("riscom8=", riscom8_setup);
1664
#endif
1665
 
1666
static char banner[] __initdata =
1667
        KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin "
1668
                  "1994-1996.\n";
1669
static char no_boards_msg[] __initdata =
1670
        KERN_INFO "rc: No RISCom/8 boards detected.\n";
1671
 
1672
/*
1673
 * This routine must be called by kernel at boot time
1674
 */
1675
static int __init riscom8_init(void)
1676
{
1677
        int i;
1678
        int found = 0;
1679
 
1680
        printk(banner);
1681
 
1682
        if (rc_init_drivers())
1683
                return -EIO;
1684
 
1685
        for (i = 0; i < RC_NBOARD; i++)
1686
                if (rc_board[i].base && !rc_probe(&rc_board[i]))
1687
                        found++;
1688
 
1689
        if (!found)  {
1690
                rc_release_drivers();
1691
                printk(no_boards_msg);
1692
                return -EIO;
1693
        }
1694
        return 0;
1695
}
1696
 
1697
#ifdef MODULE
1698
static int iobase;
1699
static int iobase1;
1700
static int iobase2;
1701
static int iobase3;
1702
module_param(iobase, int, 0);
1703
module_param(iobase1, int, 0);
1704
module_param(iobase2, int, 0);
1705
module_param(iobase3, int, 0);
1706
 
1707
MODULE_LICENSE("GPL");
1708
#endif /* MODULE */
1709
 
1710
/*
1711
 * You can setup up to 4 boards (current value of RC_NBOARD)
1712
 * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
1713
 *
1714
 */
1715
static int __init riscom8_init_module (void)
1716
{
1717
#ifdef MODULE
1718
        int i;
1719
 
1720
        if (iobase || iobase1 || iobase2 || iobase3) {
1721
                for(i = 0; i < RC_NBOARD; i++)
1722
                        rc_board[0].base = 0;
1723
        }
1724
 
1725
        if (iobase)
1726
                rc_board[0].base = iobase;
1727
        if (iobase1)
1728
                rc_board[1].base = iobase1;
1729
        if (iobase2)
1730
                rc_board[2].base = iobase2;
1731
        if (iobase3)
1732
                rc_board[3].base = iobase3;
1733
#endif /* MODULE */
1734
 
1735
        return riscom8_init();
1736
}
1737
 
1738
static void __exit riscom8_exit_module (void)
1739
{
1740
        int i;
1741
 
1742
        rc_release_drivers();
1743
        for (i = 0; i < RC_NBOARD; i++)
1744
                if (rc_board[i].flags & RC_BOARD_PRESENT)
1745
                        rc_release_io_range(&rc_board[i]);
1746
 
1747
}
1748
 
1749
module_init(riscom8_init_module);
1750
module_exit(riscom8_exit_module);
1751
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.