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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [riscom8.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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