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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [char/] [riscom8.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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