root/include/asm-m68k/serial.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. rs_sched_event
  2. rs_receive_char
  3. rs_get_tx_char
  4. rs_no_more_tx
  5. rs_dcd_changed
  6. rs_check_cts

   1 /*
   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 manu 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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 )
     /* [previous][next][first][last][top][bottom][index][help] */
 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 )
     /* [previous][next][first][last][top][bottom][index][help] */
 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 )
     /* [previous][next][first][last][top][bottom][index][help] */
 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 )
     /* [previous][next][first][last][top][bottom][index][help] */
 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 */

/* [previous][next][first][last][top][bottom][index][help] */