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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-m68k/] [serial.h] - Blame information for rev 1775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * include/linux/serial.h
3
 *
4
 * Copyright (C) 1992 by Theodore Ts'o.
5
 *
6
 * Redistribution of this file is permitted under the terms of the GNU
7
 * Public License (GPL)
8
 */
9
 
10
#ifndef _M68K_SERIAL_H
11
#define _M68K_SERIAL_H
12
 
13
 
14
/* m68k serial port types are numbered from 100 to avoid interference
15
 * with the PC types (1..4)
16
 */
17
#define PORT_UNKNOWN    0
18
#define PORT_8250       1
19
#define PORT_16450      2
20
#define PORT_16550      3
21
#define PORT_16550A     4
22
#define PORT_CIRRUS     5
23
#define SER_SCC_NORM    100     /* standard SCC channel */
24
#define SER_SCC_DMA     101     /* SCC channel with DMA support */
25
#define SER_MFP_CTRL    102     /* standard MFP port with modem control signals */
26
#define SER_MFP_BARE    103     /* MFP port without modem controls */
27
#define SER_MIDI        104     /* Atari MIDI */
28
#define SER_AMIGA       105     /* Amiga built-in serial port */
29
#define SER_IOEXT       106     /* Amiga GVP IO-Extender (16c552) */
30
#define SER_MFC_III     107     /* Amiga BSC Multiface Card III (MC68681) */
31
 
32
 
33
struct serial_struct {
34
        int     type;
35
        int     line;
36
        int     port;
37
        int     irq;
38
        int     flags;
39
        int     xmit_fifo_size;
40
        int     custom_divisor;
41
        int     baud_base;
42
        unsigned short  close_delay;
43
        char    reserved_char[2];
44
        int     hub6;
45
        unsigned short  closing_wait; /* time to wait before closing */
46
        unsigned short  closing_wait2; /* no longer used... */
47
        int     reserved[4];
48
};
49
 
50
/*
51
 * For the close wait times, 0 means wait forever for serial port to
52
 * flush its output.  65535 means don't wait at all.
53
 */
54
#define ASYNC_CLOSING_WAIT_INF  0
55
#define ASYNC_CLOSING_WAIT_NONE 65535
56
 
57
/* This function tables does the abstraction from the underlying
58
 * hardware:
59
 *
60
 *   init(): Initialize the port as necessary, set RTS and DTR and
61
 *      enable interrupts. It does not need to set the speed and other
62
 *      parameters, because change_speed() is called, too.
63
 *   deinit(): Stop and shutdown the port (e.g. disable interrupts, ...)
64
 *   enab_tx_int(): Enable or disable the Tx Buffer Empty interrupt
65
 *      independently from other interrupt sources. If the int is
66
 *      enabled, the transmitter should also be restarted, i.e. if there
67
 *      are any chars to be sent, they should be put into the Tx
68
 *      register. The real en/disabling of the interrupt may be a no-op
69
 *      if there is no way to do this or it is too complex. This Tx ints
70
 *      are just disabled to save some interrupts if the transmitter is
71
 *      stopped anyway. But the restarting must be implemented!
72
 *   check_custom_divisor(): Check the given custom divisor for legality
73
 *      and return 0 if OK, non-zero otherwise.
74
 *   change_speed(): Set port speed, character size, number of stop
75
 *      bits and parity from the termios structure. If the user wants
76
 *      to set the speed with a custom divisor, he is required to
77
 *      check the baud_base first!
78
 *   throttle(): Set or clear the RTS line according to 'status'.
79
 *   set_break(): Set or clear the 'Send a Break' flag.
80
 *   get_serial_info(): Fill in the baud_base and custom_divisor
81
 *      fields of a serial_struct. It may also modify other fields, if
82
 *      needed.
83
 *   get_modem_info(): Return the status of RTS, DTR, DCD, RI, DSR and CTS.
84
 *   set_modem_info(): Set the status of RTS and DTR according to
85
 *      'new_dtr' and 'new_rts', resp. 0 = clear, 1 = set, -1 = don't change
86
 *   ioctl(): Process any port-specific ioctl's. This pointer may be
87
 *      NULL, if the port has no own ioctl's.
88
 *   stop_receive(): Turn off the Rx part of the port, so no more characters
89
 *      will be received. This is called before shutting the port down.
90
 *   trans_empty(): Return !=0 if there are no more characters still to be
91
 *      sent out (Tx buffer register and FIFOs empty)
92
 *   check_open(): Is called before the port is opened. The driver can check
93
 *      if that's ok and return an error code, or keep track of the opening
94
 *      even before init() is called. Use deinit() for matching closing of the
95
 *      port.
96
 *
97
 */
98
 
99
struct async_struct;
100
 
101
typedef struct {
102
        void (*init)( struct async_struct *info );
103
        void (*deinit)( struct async_struct *info, int leave_dtr );
104
        void (*enab_tx_int)( struct async_struct *info, int enab_flag );
105
        int  (*check_custom_divisor)( struct async_struct *info, int baud_base,
106
                                     int divisor );
107
        void (*change_speed)( struct async_struct *info );
108
        void (*throttle)( struct async_struct *info, int status );
109
        void (*set_break)( struct async_struct *info, int break_flag );
110
        void (*get_serial_info)( struct async_struct *info,
111
                                struct serial_struct *retinfo );
112
        unsigned int (*get_modem_info)( struct async_struct *info );
113
        int  (*set_modem_info)( struct async_struct *info, int new_dtr,
114
                               int new_rts );
115
        int  (*ioctl)( struct tty_struct *tty, struct file *file,
116
                      struct async_struct *info, unsigned int cmd,
117
                      unsigned long arg );
118
        void (*stop_receive)( struct async_struct *info );
119
        int  (*trans_empty)( struct async_struct *info );
120
        int  (*check_open)( struct async_struct *info, struct tty_struct *tty,
121
                           struct file *file );
122
} SERIALSWITCH;
123
 
124
/*
125
 * Definitions for async_struct (and serial_struct) flags field
126
 */
127
#define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
128
                                   on the callout port */
129
#define ASYNC_FOURPORT  0x0002  /* Set OU1, OUT2 per AST Fourport settings */
130
#define ASYNC_SAK       0x0004  /* Secure Attention Key (Orange book) */
131
#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
132
 
133
#define ASYNC_SPD_MASK  0x0030
134
#define ASYNC_SPD_HI    0x0010  /* Use 56000 instead of 38400 bps */
135
 
136
#define ASYNC_SPD_VHI   0x0020  /* Use 115200 instead of 38400 bps */
137
#define ASYNC_SPD_CUST  0x0030  /* Use user-specified divisor */
138
 
139
#define ASYNC_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */
140
#define ASYNC_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
141
#define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
142
#define ASYNC_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
143
#define ASYNC_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
144
 
145
#define ASYNC_FLAGS     0x0FFF  /* Possible legal async flags */
146
#define ASYNC_USR_MASK 0x0430   /* Legal flags that non-privileged
147
                                 * users can set or reset */
148
 
149
/* Internal flags used only by drivers/char/m68kserial.c */
150
#define ASYNC_INITIALIZED       0x80000000 /* Serial port was initialized */
151
#define ASYNC_CALLOUT_ACTIVE    0x40000000 /* Call out device is active */
152
#define ASYNC_NORMAL_ACTIVE     0x20000000 /* Normal device is active */
153
#define ASYNC_BOOT_AUTOCONF     0x10000000 /* Autoconfigure port on bootup */
154
#define ASYNC_CLOSING           0x08000000 /* Serial port is closing */
155
#define ASYNC_CTS_FLOW          0x04000000 /* Do CTS flow control */
156
#define ASYNC_CHECK_CD          0x02000000 /* i.e., CLOCAL */
157
 
158
/*
159
 * Serial input interrupt line counters -- external structure
160
 * Four lines can interrupt: CTS, DSR, RI, DCD
161
 */
162
struct serial_icounter_struct {
163
        int cts, dsr, rng, dcd;
164
        int reserved[16];
165
};
166
 
167
 
168
#ifdef __KERNEL__
169
/*
170
 * This is our internal structure for each serial port's state.
171
 *
172
 * Many fields are paralleled by the structure used by the serial_struct
173
 * structure.
174
 *
175
 * For definitions of the flags field, see tty.h
176
 */
177
 
178
#include <linux/termios.h>
179
#include <linux/tqueue.h>
180
 
181
/*
182
 * Counters of the input lines (CTS, DSR, RI, CD) interrupts
183
 */
184
struct async_icount {
185
        __u32   cts, dsr, rng, dcd;
186
};
187
 
188
struct async_struct {
189
        int                     magic;
190
        int                     baud_base;
191
        int                     port;
192
        int                     irq;
193
        int                     flags;          /* defined in tty.h */
194
        int                     hub6;           /* HUB6 plus one */
195
        int                     type;
196
        struct tty_struct       *tty;
197
        int                     read_status_mask;
198
        int                     ignore_status_mask;
199
        int                     timeout;
200
        int                     xmit_fifo_size;
201
        int                     custom_divisor;
202
        int                     x_char; /* xon/xoff character */
203
        int                     close_delay;
204
        unsigned short          closing_wait;
205
        unsigned short          closing_wait2;
206
        int                     IER;    /* Interrupt Enable Register */
207
        int                     MCR;    /* Modem control register */
208
        int                     MCR_noint; /* MCR with interrupts off */
209
        unsigned long           event;
210
        unsigned long           last_active;
211
        int                     line;
212
        int                     count;      /* # of fd on device */
213
        int                     blocked_open; /* # of blocked opens */
214
        long                    session; /* Session of opening process */
215
        long                    pgrp; /* pgrp of opening process */
216
        unsigned char           *xmit_buf;
217
        int                     xmit_head;
218
        int                     xmit_tail;
219
        int                     xmit_cnt;
220
        struct tq_struct        tqueue;
221
        struct tq_struct        tqueue_hangup;
222
        struct termios          normal_termios;
223
        struct termios          callout_termios;
224
        struct wait_queue       *open_wait;
225
        struct wait_queue       *close_wait;
226
        struct wait_queue       *delta_msr_wait;
227
        struct async_icount     icount; /* kernel counters for the 4 input interrupts */
228
        struct async_struct     *next_port; /* For the linked list */
229
        struct async_struct     *prev_port;
230
        void                    *board_base; /* board-base address for use with
231
                                                boards carrying several UART's,
232
                                                like some Amiga boards. */
233
        unsigned short          nr_uarts;    /* UART-counter, that indicates
234
                                                how many UART's there are on
235
                                                the board.  If the board has a
236
                                                IRQ-register, this can be used
237
                                                to check if any of the uarts,
238
                                                on the board has requested an
239
                                                interrupt, instead of checking
240
                                                IRQ-registers on all UART's */
241
        SERIALSWITCH            *sw;            /* functions to manage this port */
242
};
243
 
244
#define SERIAL_MAGIC 0x5301
245
 
246
/*
247
 * The size of the serial xmit buffer is 1 page, or 4096 bytes
248
 */
249
#define SERIAL_XMIT_SIZE 4096
250
 
251
/*
252
 * Events are used to schedule things to happen at timer-interrupt
253
 * time, instead of at rs interrupt time.
254
 */
255
#define RS_EVENT_WRITE_WAKEUP   0
256
 
257
/* number of characters left in xmit buffer before we ask for more */
258
#define WAKEUP_CHARS 256
259
 
260
/* Export to allow PCMCIA to use this - Dave Hinds */
261
extern int register_serial(struct serial_struct *req);
262
extern void unregister_serial(int line);
263
extern struct async_struct rs_table[];
264
extern task_queue tq_serial;
265
 
266
 
267
/*
268
 * This routine is used by the interrupt handler to schedule
269
 * processing in the software interrupt portion of the driver.
270
 */
271
static __inline__ void rs_sched_event(struct async_struct *info, int event)
272
{
273
        info->event |= 1 << event;
274
        queue_task_irq(&info->tqueue, &tq_serial);
275
        mark_bh(SERIAL_BH);
276
}
277
 
278
static __inline__ void rs_receive_char( struct async_struct *info,
279
                                            int ch, int err )
280
{
281
        struct tty_struct *tty = info->tty;
282
 
283
        if (tty->flip.count >= TTY_FLIPBUF_SIZE)
284
                return;
285
        tty->flip.count++;
286
        if (err == TTY_BREAK) {
287
                if (info->flags & ASYNC_SAK)
288
                        do_SAK(tty);
289
        }
290
        *tty->flip.flag_buf_ptr++ = err;
291
        *tty->flip.char_buf_ptr++ = ch;
292
        queue_task_irq(&tty->flip.tqueue, &tq_timer);
293
}
294
 
295
static __inline__ int rs_get_tx_char( struct async_struct *info )
296
{
297
        unsigned char ch;
298
 
299
        if (info->x_char) {
300
                ch = info->x_char;
301
                info->x_char = 0;
302
                return( ch );
303
        }
304
 
305
        if (info->xmit_cnt <= 0 || info->tty->stopped || info->tty->hw_stopped)
306
                return( -1 );
307
 
308
        ch = info->xmit_buf[info->xmit_tail++];
309
        info->xmit_tail &= SERIAL_XMIT_SIZE - 1;
310
        if (--info->xmit_cnt < WAKEUP_CHARS)
311
                rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
312
        return( ch );
313
}
314
 
315
static __inline__ int rs_no_more_tx( struct async_struct *info )
316
{
317
        return( info->xmit_cnt <= 0 ||
318
                        info->tty->stopped ||
319
                        info->tty->hw_stopped );
320
}
321
 
322
static __inline__ void rs_dcd_changed( struct async_struct *info, int dcd )
323
 
324
{
325
        /* update input line counter */
326
        info->icount.dcd++;
327
        wake_up_interruptible(&info->delta_msr_wait);
328
 
329
        if (info->flags & ASYNC_CHECK_CD) {
330
#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
331
                printk("ttyS%d CD now %s...", info->line,
332
                       dcd ? "on" : "off");
333
#endif          
334
                if (dcd) {
335
                        wake_up_interruptible(&info->open_wait);
336
                } else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
337
                             (info->flags & ASYNC_CALLOUT_NOHUP))) {
338
#ifdef SERIAL_DEBUG_OPEN
339
                        printk("scheduling hangup...");
340
#endif
341
                        queue_task_irq(&info->tqueue_hangup,
342
                                       &tq_scheduler);
343
                }
344
        }
345
}
346
 
347
 
348
void rs_stop( struct tty_struct *tty );
349
void rs_start( struct tty_struct *tty );
350
 
351
static __inline__ void rs_check_cts( struct async_struct *info, int cts )
352
{
353
        /* update input line counter */
354
        info->icount.cts++;
355
        wake_up_interruptible(&info->delta_msr_wait);
356
 
357
        if ((info->flags & ASYNC_CTS_FLOW) && info->tty)
358
                if (info->tty->hw_stopped) {
359
                        if (cts) {
360
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
361
                                printk("CTS tx start...");
362
#endif
363
                                info->tty->hw_stopped = 0;
364
                                rs_start( info->tty );
365
                                rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
366
                                return;
367
                        }
368
                } else {
369
                        if (!cts) {
370
                                info->tty->hw_stopped = 1;
371
                                rs_stop( info->tty );
372
                        }
373
                }
374
 
375
}
376
 
377
 
378
#endif /* __KERNEL__ */
379
 
380
#endif /* _M68K_SERIAL_H */

powered by: WebSVN 2.1.0

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