/* * Device driver for Specialix range (SLXOS) of serial line multiplexors. * 'C' definitions for Specialix serial multiplex driver. * * Copyright (C) 1990, 1992 Specialix International, * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk> * Copyright (C) 1995, Peter Wemm <peter@haywire.dialix.com> * * Derived from: SunOS 4.x version * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notices, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Andy Rutter of * Advanced Methods and Tools Ltd. based on original information * from Specialix International. * 4. Neither the name of Advanced Methods and Tools, nor Specialix * International may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHORS BE LIABLE. * * $Id: si.h,v 1.3 1995/08/22 00:42:07 peter Exp $ */ /* * Macro to turn a device number into various parameters, and test for * CONTROL device. * max of 4 controllers with up to 32 ports per controller. * minor device allocation is: * adapter port * 0 0-31 * 1 32-63 * 2 64-95 * 3 96-127 */ #define SI_MAXPORTPERCARD 32 #define SI_MAXCONTROLLER 4 /* * breakup of minor device number: * lowest 5 bits: port number on card 0x1f * next 2 bits: card number 0x60 * top bit: callout 0x80 * next 8 bits is the major number * next 2 bits select initial/lock states * next 1 bit selects the master control device */ #define SI_PORT_MASK 0x1f #define SI_CARD_MASK 0x60 #define SI_TTY_MASK 0x7f #define SI_CALLOUT_MASK 0x80 #define SI_INIT_STATE_MASK 0x10000 #define SI_LOCK_STATE_MASK 0x20000 #define SI_STATE_MASK 0x30000 #define SI_CONTROLDEV_MASK 0x40000 #define SI_SPECIAL_MASK 0x70000 #define SI_PORT(m) (m & SI_PORT_MASK) #define SI_CARD(m) ((m & SI_CARD_MASK) >> 5) #define SI_TTY(m) (m & SI_TTY_MASK) #define IS_CALLOUT(m) (m & SI_CALLOUT_MASK) #define IS_STATE(m) (m & SI_STATE_MASK) #define IS_CONTROLDEV(m) (m & SI_CONTROLDEV_MASK) #define IS_SPECIAL(m) (m & SI_SPECIAL_MASK) #define MINOR2SC(m) (&si_softc[SI_CARD(m)]) #define MINOR2PP(m) (MINOR2SC((m))->sc_ports + SI_PORT((m))) #define MINOR2TP(m) (MINOR2PP((m))->sp_tty) #define TP2PP(tp) (MINOR2PP(SI_TTY(minor((tp)->t_dev)))) /* Adapter types */ #define SIEMPTY 0 #define SIHOST 1 #define SI2 2 #define SIHOST2 3 #define SIEISA 4 /* Buffer parameters */ #define SLXOS_BUFFERSIZE 256 typedef unsigned char BYTE; /* Type cast for unsigned 8 bit */ typedef unsigned short WORD; /* Type cast for unsigned 16 bit */ /* * Hardware `registers', stored in the shared memory. * These are related to the firmware running on the Z280. */ struct si_reg { BYTE initstat; BYTE memsize; WORD int_count; WORD revision; BYTE rx_int_count; BYTE spare; WORD int_pending; WORD int_counter; BYTE int_scounter; BYTE res[0x80 - 13]; }; /* * Per module control structure, stored in shared memory. */ struct si_module { WORD sm_next; /* Next module */ BYTE sm_type; /* Number of channels */ BYTE sm_number; /* Module number on cable */ BYTE sm_dsr; /* Private dsr copy */ BYTE sm_res[0x80 - 5]; /* Reserve space to 128 bytes */ }; /* * The 'next' pointer & with 0x7fff + SI base addres give * the address of the next module block if fitted. (else 0) * Note that next points to the TX buffer so 0x60 must be * subtracted to find the true base. * * Type is a bit field as follows: The bottom 5 bits are the * number of channels on this module, the top 3 bits are * as the module type thus: * * 000 2698 RS232 module (4 port or 8 port) * 001 Reserved for 2698 RS422 module * 010 Reserved for 8530 based sync module * 011 Reserved for parallel printer module * 100 Reserved for network module * 101-111 Reserved for expansion. * * The number field is the cable position of the module. */ #define M232 0x00 #define M422 0x20 /* not supported */ #define MSYNC 0x40 /* this is the Telebit Netblazer module */ #define MCENT 0x60 /* not supported */ #define MNET 0x80 /* not supported */ #define MMASK 0x1F /* * Per channel(port) control structure, stored in shared memory. */ struct si_channel { /* * Generic stuff */ WORD next; /* Next Channel */ WORD addr_uart; /* Uart address */ WORD module; /* address of module struct */ BYTE type; /* Uart type */ BYTE fill; /* * Uart type specific stuff */ BYTE x_status; /* XON / XOFF status */ BYTE c_status; /* cooking status */ BYTE hi_rxipos; /* stuff into rx buff */ BYTE hi_rxopos; /* stuff out of rx buffer */ BYTE hi_txopos; /* Stuff into tx ptr */ BYTE hi_txipos; /* ditto out */ BYTE hi_stat; /* Command register */ BYTE dsr_bit; /* Magic bit for DSR */ BYTE txon; /* TX XON char */ BYTE txoff; /* ditto XOFF */ BYTE rxon; /* RX XON char */ BYTE rxoff; /* ditto XOFF */ BYTE hi_mr1; /* mode 1 image */ BYTE hi_mr2; /* mode 2 image */ BYTE hi_csr; /* clock register */ BYTE hi_op; /* Op control */ BYTE hi_ip; /* Input pins */ BYTE hi_state; /* status */ BYTE hi_prtcl; /* Protocol */ BYTE hi_txon; /* host copy tx xon stuff */ BYTE hi_txoff; BYTE hi_rxon; BYTE hi_rxoff; BYTE close_prev; /* Was channel previously closed */ BYTE hi_break; /* host copy break process */ BYTE break_state; /* local copy ditto */ BYTE hi_mask; /* Mask for CS7 etc. */ BYTE mask_z280; /* Z280's copy */ BYTE res[0x60 - 36]; BYTE hi_txbuf[SLXOS_BUFFERSIZE]; BYTE hi_rxbuf[SLXOS_BUFFERSIZE]; BYTE res1[0xA0]; }; /* * Register definitions */ /* * Break input control register definitions */ #define BR_IGN 0x01 /* Ignore any received breaks */ #define BR_INT 0x02 /* Interrupt on received break */ #define BR_PARMRK 0x04 /* Enable parmrk parity error processing */ #define BR_PARIGN 0x08 /* Ignore chars with parity errors */ /* * Protocol register provided by host for XON/XOFF and cooking */ #define SP_TANY 0x01 /* Tx XON any char */ #define SP_TXEN 0x02 /* Tx XON/XOFF enabled */ #define SP_CEN 0x04 /* Cooking enabled */ #define SP_RXEN 0x08 /* Rx XON/XOFF enabled */ #define SP_DCEN 0x20 /* DCD / DTR check */ #define SP_PAEN 0x80 /* Parity checking enabled */ /* * HOST STATUS / COMMAND REGISTER */ #define IDLE_OPEN 0x00 /* Default mode, TX and RX polled buffer updated etc */ #define LOPEN 0x02 /* Local open command (no modem ctl */ #define MOPEN 0x04 /* Open and monitor modem lines (blocks for DCD */ #define MPEND 0x06 /* Wating for DCD */ #define CONFIG 0x08 /* Channel config has changed */ #define CLOSE 0x0A /* Close channel */ #define SBREAK 0x0C /* Start break */ #define EBREAK 0x0E /* End break */ #define IDLE_CLOSE 0x10 /* Closed channel */ #define IDLE_BREAK 0x12 /* In a break */ #define FCLOSE 0x14 /* Force a close */ #define RESUME 0x16 /* Clear a pending xoff */ #define WFLUSH 0x18 /* Flush output buffer */ #define RFLUSH 0x1A /* Flush input buffer */ /* * Host status register */ #define ST_BREAK 0x01 /* Break received (clear with config) */ /* * OUTPUT PORT REGISTER */ #define OP_CTS 0x01 /* Enable CTS */ #define OP_DSR 0x02 /* Enable DSR */ /* * INPUT PORT REGISTER */ #define IP_DCD 0x04 /* DCD High */ #define IP_DTR 0x20 /* DTR High */ #define IP_RTS 0x02 /* RTS High */ #define IP_RI 0x40 /* RI High */ /* * Mode register and uart specific stuff */ /* * MODE REGISTER 1 */ #define MR1_5_BITS 0x00 #define MR1_6_BITS 0x01 #define MR1_7_BITS 0x02 #define MR1_8_BITS 0x03 /* * Parity */ #define MR1_ODD 0x04 #define MR1_EVEN 0x00 /* * Parity mode */ #define MR1_WITH 0x00 #define MR1_FORCE 0x08 #define MR1_NONE 0x10 #define MR1_SPECIAL 0x18 /* * Error mode */ #define MR1_CHAR 0x00 #define MR1_BLOCK 0x20 /* * Request to send line automatic control */ #define MR1_CTSCONT 0x80 /* * MODE REGISTER 2 */ /* * Number of stop bits */ #define MR2_1_STOP 0x07 #define MR2_2_STOP 0x0F /* * Clear to send automatic testing before character sent */ #define MR2_RTSCONT 0x10 /* * Reset RTS automatically after sending character? */ #define MR2_CTSCONT 0x20 /* * Channel mode */ #define MR2_NORMAL 0x00 #define MR2_AUTO 0x40 #define MR2_LOCAL 0x80 #define MR2_REMOTE 0xC0 /* * CLOCK SELECT REGISTER - this and the code assumes ispeed == ospeed */ /* * Clocking rates are in lower and upper nibbles.. R = upper, T = lower */ #define CLK75 0x0 #define CLK110 0x1 /* 110 on XIO!! */ #define CLK38400 0x2 /* out of sequence */ #define CLK150 0x3 #define CLK300 0x4 #define CLK600 0x5 #define CLK1200 0x6 #define CLK2000 0x7 #define CLK2400 0x8 #define CLK4800 0x9 #define CLK7200 0xa /* unchecked */ #define CLK9600 0xb #define CLK19200 0xc #define CLK57600 0xd /* * Per-port (channel) soft information structure, stored in the driver. * This is visible via ioctl()'s. */ struct si_port { volatile struct si_channel *sp_ccb; struct tty *sp_tty; int sp_pend; /* pending command */ int sp_last_hi_ip; /* cached DCD */ int sp_state; int sp_active_out; /* callout is open */ int sp_flags; int sp_dtr_wait; /* DTR holddown in hz */ u_int sp_wopeners; /* # procs waiting DCD */ u_char sp_hotchar; /* ldisc specific ASAP char */ /* Initial state. */ struct termios sp_iin; struct termios sp_iout; /* Lock state. */ struct termios sp_lin; struct termios sp_lout; #ifdef SI_DEBUG int sp_debug; /* debug mask */ #endif }; /* sp_state */ #define SS_CLOSED 0x0000 #define SS_OPEN 0x0001 /* Port is active */ /* 0x0002 -- */ /* 0x0004 -- */ /* 0x0008 -- */ /* 0x0010 -- */ /* 0x0020 -- */ /* 0x0040 -- */ /* 0x0080 -- */ #define SS_LSTART 0x0100 /* lstart timeout pending */ #define SS_INLSTART 0x0200 /* running an lstart induced t_oproc */ #define SS_CLOSING 0x0400 /* in the middle of a siclose() */ /* 0x0800 -- */ #define SS_WAITWRITE 0x1000 #define SS_BLOCKWRITE 0x2000 #define SS_DTR_OFF 0x4000 /* DTR held off */ /* sp_flags */ #define SPF_COOKMODE 0x0003 #define SPFC_WELL 0 #define SPFC_MEDIUM 1 #define SPFC_RAW 2 #define spfc_clear(pp) (pp)->sp_flags &= ~SPF_COOKMODE #define SPF_COOK_WELL(pp) spfc_clear(pp) #define SPF_COOK_MEDIUM(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_MEDIUM;} #define SPF_COOK_RAW(pp) {spfc_clear(pp);(pp)->sp_flags|=SPFC_RAW;} #define SPF_SETCOOK(pp, c) {spfc_clear(pp);(pp)->sp_flags|=(c);} #define SPF_ISCOOKWELL(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_WELL) #define SPF_ISCOOKMEDIUM(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_MEDIUM) #define SPF_ISCOOKRAW(pp) (((pp)->sp_flags & SPF_COOKMODE) == SPFC_RAW) #define SPF_COOKWELL_ALWAYS 0x0004 /* always use line disc */ /* 0x0008 */ #define SPF_IXANY 0x0020 /* IXANY enable/disable flag */ #define SPF_CTSOFLOW 0x0040 /* use CTS to handle o/p flow */ #define SPF_RTSIFLOW 0x0080 /* use RTS to handle i/p flow */ #define SPF_PPP 0x0100 /* special handling for upper * level protocol code */ /* * Command post flags */ #define SI_NOWAIT 0x00 /* Don't wait for command */ #define SI_WAIT 0x01 /* Wait for complete */ /* * Extensive debugging stuff - manipulated using siconfig(8) */ #define DBG_ENTRY 0x00000001 #define DBG_DRAIN 0x00000002 #define DBG_OPEN 0x00000004 #define DBG_CLOSE 0x00000008 #define DBG_READ 0x00000010 #define DBG_WRITE 0x00000020 #define DBG_PARAM 0x00000040 #define DBG_INTR 0x00000080 #define DBG_IOCTL 0x00000100 /* 0x00000200 */ #define DBG_SELECT 0x00000400 #define DBG_OPTIM 0x00000800 #define DBG_START 0x00001000 #define DBG_EXIT 0x00002000 #define DBG_FAIL 0x00004000 #define DBG_STOP 0x00008000 #define DBG_AUTOBOOT 0x00010000 #define DBG_MODEM 0x00020000 #define DBG_DOWNLOAD 0x00040000 #define DBG_LSTART 0x00080000 #define DBG_POLL 0x00100000 #define DBG_ALL 0xffffffff /* * SI ioctls */ /* * struct for use by Specialix ioctls - used by siconfig(8) */ typedef struct { unsigned char sid_port:5, /* 0 - 31 ports per card */ sid_card:2, /* 0 - 3 cards */ sid_control:1; /* controlling device (all cards) */ } sidev_t; struct si_tcsi { sidev_t tc_dev; union { int x_int; int x_dbglvl; } tc_action; #define tc_card tc_dev.sid_card #define tc_port tc_dev.sid_port #define tc_int tc_action.x_int #define tc_dbglvl tc_action.x_dbglvl }; struct si_pstat { sidev_t tc_dev; union { struct si_port x_siport; struct si_channel x_ccb; struct tty x_tty; } tc_action; #define tc_siport tc_action.x_siport #define tc_ccb tc_action.x_ccb #define tc_tty tc_action.x_tty }; #define IOCTL_MIN 96 #define TCSIDEBUG _IOW('S', 96, struct si_tcsi) /* Toggle debug */ #define TCSIRXIT _IOW('S', 97, struct si_tcsi) /* RX int throttle */ #define TCSIIT _IOW('S', 98, struct si_tcsi) /* TX int throttle */ /* 99 defunct */ /* 100 defunct */ /* 101 defunct */ /* 102 defunct */ /* 103 defunct */ #define TCSIIXANY _IOW('S', 103, struct si_tcsi) /* enable ixany */ /* 104 defunct */ #define TCSISTATE _IOWR('S', 105, struct si_tcsi) /* get current state of RTS DCD and DTR pins */ /* Set/reset/enquire cook mode, 1 = always use line disc * -1 = enquire current setting */ #define TCSICOOKMODE _IOWR('S', 106, struct si_tcsi) #define TCSIPORTS _IOR('S', 107, int) /* Number of ports found */ #define TCSISDBG_LEVEL _IOW('S', 108, struct si_tcsi) /* equivalent of TCSIDEBUG which sets a * particular debug level (DBG_??? bit * mask), default is 0xffff */ #define TCSIGDBG_LEVEL _IOWR('S', 109, struct si_tcsi) #define TCSIGRXIT _IOWR('S', 110, struct si_tcsi) #define TCSIGIT _IOWR('S', 111, struct si_tcsi) /* 112 defunct */ /* 113 defunct */ /* 114 defunct */ /* 115 defunct */ /* 116 defunct */ #define TCSIMODEM _IOWR('S', 117, struct si_tcsi) /* set/clear/query the modem bit */ #define TCSISDBG_ALL _IOW('S', 118, int) /* set global debug level */ #define TCSIGDBG_ALL _IOR('S', 119, int) /* get global debug level */ #define TCSIFLOW _IOWR('S', 120, struct si_tcsi) /* set/get h/w flow state */ /* 121 defunct */ /* 122 defunct */ #define TCSIPPP _IOWR('S', 123, struct si_tcsi) /* set/get PPP flag bit */ #define TCSIMODULES _IOR('S', 124, int) /* Number of modules found */ /* Various stats and monitoring hooks per tty device */ #define TCSI_PORT _IOWR('S', 125, struct si_pstat) /* get si_port */ #define TCSI_CCB _IOWR('S', 126, struct si_pstat) /* get si_ccb */ #define TCSI_TTY _IOWR('S', 127, struct si_pstat) /* get tty struct */ #define IOCTL_MAX 127 #define IS_SI_IOCTL(cmd) ((u_int)((cmd)&0xff00) == ('S'<<8) && \ (u_int)((cmd)&0xff) >= IOCTL_MIN && \ (u_int)((cmd)&0xff) <= IOCTL_MAX) #define CONTROLDEV "/dev/si_control"