1139749Simp/*- 212496Speter * Device driver for Specialix range (SI/XIO) of serial line multiplexors. 310015Speter * 'C' definitions for Specialix serial multiplex driver. 410015Speter * 534832Speter * Copyright (C) 1990, 1992, 1998 Specialix International, 610015Speter * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk> 734832Speter * Copyright (C) 1995, Peter Wemm <peter@netplex.com.au> 810015Speter * 910015Speter * Derived from: SunOS 4.x version 1010015Speter * 1110015Speter * Redistribution and use in source and binary forms, with or without 1210015Speter * modification, are permitted provided that the following conditions 1310015Speter * are met: 1410015Speter * 1. Redistributions of source code must retain the above copyright 1510015Speter * notices, this list of conditions and the following disclaimer. 1610015Speter * 2. Redistributions in binary form must reproduce the above copyright 1710015Speter * notices, this list of conditions and the following disclaimer in the 1810015Speter * documentation and/or other materials provided with the distribution. 1910015Speter * 3. All advertising materials mentioning features or use of this software 2010015Speter * must display the following acknowledgement: 2110015Speter * This product includes software developed by Andy Rutter of 2210015Speter * Advanced Methods and Tools Ltd. based on original information 2310015Speter * from Specialix International. 2410015Speter * 4. Neither the name of Advanced Methods and Tools, nor Specialix 2510015Speter * International may be used to endorse or promote products derived from 2610015Speter * this software without specific prior written permission. 2710015Speter * 2810015Speter * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED 2910015Speter * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 3010015Speter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 3110015Speter * NO EVENT SHALL THE AUTHORS BE LIABLE. 3210015Speter * 3350477Speter * $FreeBSD$ 3410015Speter */ 3510015Speter 3629676Sgibbs#include <sys/callout.h> 3729676Sgibbs 3810015Speter/* 39136058Sphk * We name devices with %r in make_dev() with a radix of 32. 40136058Sphk */ 4110015Speter#define SI_MAXPORTPERCARD 32 4210015Speter 4310015Speter/* Buffer parameters */ 4412496Speter#define SI_BUFFERSIZE 256 4510015Speter 46136058Sphktypedef uint8_t BYTE; /* Type cast for unsigned 8 bit */ 47136058Sphktypedef uint16_t WORD; /* Type cast for unsigned 16 bit */ 4810015Speter 4910015Speter/* 5010015Speter * Hardware `registers', stored in the shared memory. 5110015Speter * These are related to the firmware running on the Z280. 5210015Speter */ 5310015Speter 5410015Speterstruct si_reg { 5510015Speter BYTE initstat; 5610015Speter BYTE memsize; 5710015Speter WORD int_count; 5810015Speter WORD revision; 5934832Speter BYTE rx_int_count; /* isr_count on Jet */ 6034832Speter BYTE main_count; /* spare on Z-280 */ 6110015Speter WORD int_pending; 6210015Speter WORD int_counter; 6310015Speter BYTE int_scounter; 6410015Speter BYTE res[0x80 - 13]; 6510015Speter}; 6610015Speter 6710015Speter/* 6810015Speter * Per module control structure, stored in shared memory. 6910015Speter */ 7010015Speterstruct si_module { 7110015Speter WORD sm_next; /* Next module */ 7210015Speter BYTE sm_type; /* Number of channels */ 7310015Speter BYTE sm_number; /* Module number on cable */ 7410015Speter BYTE sm_dsr; /* Private dsr copy */ 7510015Speter BYTE sm_res[0x80 - 5]; /* Reserve space to 128 bytes */ 7610015Speter}; 7710015Speter 7810015Speter/* 7910015Speter * The 'next' pointer & with 0x7fff + SI base addres give 8010015Speter * the address of the next module block if fitted. (else 0) 8110015Speter * Note that next points to the TX buffer so 0x60 must be 8210015Speter * subtracted to find the true base. 8310015Speter */ 8434832Speter#define TA4 0x00 8534832Speter#define TA8 0x08 8634832Speter#define TA4_ASIC 0x0A 8734832Speter#define TA8_ASIC 0x0B 8834832Speter#define MTA 0x28 8934832Speter#define SXDC 0x48 9010015Speter 9110015Speter/* 9210015Speter * Per channel(port) control structure, stored in shared memory. 9310015Speter */ 9410015Speterstruct si_channel { 9510015Speter /* 9610015Speter * Generic stuff 9710015Speter */ 9810015Speter WORD next; /* Next Channel */ 9910015Speter WORD addr_uart; /* Uart address */ 10010015Speter WORD module; /* address of module struct */ 10110015Speter BYTE type; /* Uart type */ 10210015Speter BYTE fill; 10310015Speter /* 10410015Speter * Uart type specific stuff 10510015Speter */ 10610015Speter BYTE x_status; /* XON / XOFF status */ 10710015Speter BYTE c_status; /* cooking status */ 10810015Speter BYTE hi_rxipos; /* stuff into rx buff */ 10910015Speter BYTE hi_rxopos; /* stuff out of rx buffer */ 11010015Speter BYTE hi_txopos; /* Stuff into tx ptr */ 11110015Speter BYTE hi_txipos; /* ditto out */ 11210015Speter BYTE hi_stat; /* Command register */ 11310015Speter BYTE dsr_bit; /* Magic bit for DSR */ 11410015Speter BYTE txon; /* TX XON char */ 11510015Speter BYTE txoff; /* ditto XOFF */ 11610015Speter BYTE rxon; /* RX XON char */ 11710015Speter BYTE rxoff; /* ditto XOFF */ 11810015Speter BYTE hi_mr1; /* mode 1 image */ 11910015Speter BYTE hi_mr2; /* mode 2 image */ 12010015Speter BYTE hi_csr; /* clock register */ 12110015Speter BYTE hi_op; /* Op control */ 12210015Speter BYTE hi_ip; /* Input pins */ 12310015Speter BYTE hi_state; /* status */ 12410015Speter BYTE hi_prtcl; /* Protocol */ 12510015Speter BYTE hi_txon; /* host copy tx xon stuff */ 12610015Speter BYTE hi_txoff; 12710015Speter BYTE hi_rxon; 12810015Speter BYTE hi_rxoff; 12910015Speter BYTE close_prev; /* Was channel previously closed */ 13010015Speter BYTE hi_break; /* host copy break process */ 13110015Speter BYTE break_state; /* local copy ditto */ 13210015Speter BYTE hi_mask; /* Mask for CS7 etc. */ 13310015Speter BYTE mask_z280; /* Z280's copy */ 13410015Speter BYTE res[0x60 - 36]; 13512496Speter BYTE hi_txbuf[SI_BUFFERSIZE]; 13612496Speter BYTE hi_rxbuf[SI_BUFFERSIZE]; 13710015Speter BYTE res1[0xA0]; 13810015Speter}; 13910015Speter 14010015Speter/* 14110015Speter * Register definitions 14210015Speter */ 14310015Speter 14410015Speter/* 14510015Speter * Break input control register definitions 14610015Speter */ 14710015Speter#define BR_IGN 0x01 /* Ignore any received breaks */ 14810015Speter#define BR_INT 0x02 /* Interrupt on received break */ 14910015Speter#define BR_PARMRK 0x04 /* Enable parmrk parity error processing */ 15010015Speter#define BR_PARIGN 0x08 /* Ignore chars with parity errors */ 15110015Speter 15210015Speter/* 15310015Speter * Protocol register provided by host for XON/XOFF and cooking 15410015Speter */ 15510015Speter#define SP_TANY 0x01 /* Tx XON any char */ 15610015Speter#define SP_TXEN 0x02 /* Tx XON/XOFF enabled */ 15710015Speter#define SP_CEN 0x04 /* Cooking enabled */ 15810015Speter#define SP_RXEN 0x08 /* Rx XON/XOFF enabled */ 15910015Speter#define SP_DCEN 0x20 /* DCD / DTR check */ 16010015Speter#define SP_PAEN 0x80 /* Parity checking enabled */ 16110015Speter 16210015Speter/* 16310015Speter * HOST STATUS / COMMAND REGISTER 16410015Speter */ 16510015Speter#define IDLE_OPEN 0x00 /* Default mode, TX and RX polled 16610015Speter buffer updated etc */ 16710015Speter#define LOPEN 0x02 /* Local open command (no modem ctl */ 16810015Speter#define MOPEN 0x04 /* Open and monitor modem lines (blocks 16910015Speter for DCD */ 17010015Speter#define MPEND 0x06 /* Wating for DCD */ 17110015Speter#define CONFIG 0x08 /* Channel config has changed */ 17210015Speter#define CLOSE 0x0A /* Close channel */ 17310015Speter#define SBREAK 0x0C /* Start break */ 17410015Speter#define EBREAK 0x0E /* End break */ 17510015Speter#define IDLE_CLOSE 0x10 /* Closed channel */ 17610015Speter#define IDLE_BREAK 0x12 /* In a break */ 17710015Speter#define FCLOSE 0x14 /* Force a close */ 17810015Speter#define RESUME 0x16 /* Clear a pending xoff */ 17910015Speter#define WFLUSH 0x18 /* Flush output buffer */ 18010015Speter#define RFLUSH 0x1A /* Flush input buffer */ 18110015Speter 18210015Speter/* 18310015Speter * Host status register 18410015Speter */ 18510015Speter#define ST_BREAK 0x01 /* Break received (clear with config) */ 18610015Speter 18710015Speter/* 18810015Speter * OUTPUT PORT REGISTER 18910015Speter */ 19010015Speter#define OP_CTS 0x01 /* Enable CTS */ 19110015Speter#define OP_DSR 0x02 /* Enable DSR */ 19210015Speter/* 19310015Speter * INPUT PORT REGISTER 19410015Speter */ 19510015Speter#define IP_DCD 0x04 /* DCD High */ 19610015Speter#define IP_DTR 0x20 /* DTR High */ 19710015Speter#define IP_RTS 0x02 /* RTS High */ 19810015Speter#define IP_RI 0x40 /* RI High */ 19910015Speter 20010015Speter/* 20110015Speter * Mode register and uart specific stuff 20210015Speter */ 20310015Speter/* 20410015Speter * MODE REGISTER 1 20510015Speter */ 20610015Speter#define MR1_5_BITS 0x00 20710015Speter#define MR1_6_BITS 0x01 20810015Speter#define MR1_7_BITS 0x02 20910015Speter#define MR1_8_BITS 0x03 21010015Speter/* 21110015Speter * Parity 21210015Speter */ 21310015Speter#define MR1_ODD 0x04 21410015Speter#define MR1_EVEN 0x00 21510015Speter/* 21610015Speter * Parity mode 21710015Speter */ 21810015Speter#define MR1_WITH 0x00 21910015Speter#define MR1_FORCE 0x08 22010015Speter#define MR1_NONE 0x10 22110015Speter#define MR1_SPECIAL 0x18 22210015Speter/* 22310015Speter * Error mode 22410015Speter */ 22510015Speter#define MR1_CHAR 0x00 22610015Speter#define MR1_BLOCK 0x20 22710015Speter/* 22810015Speter * Request to send line automatic control 22910015Speter */ 23010015Speter#define MR1_CTSCONT 0x80 23110015Speter 23210015Speter/* 23310015Speter * MODE REGISTER 2 23410015Speter */ 23510015Speter/* 23610015Speter * Number of stop bits 23710015Speter */ 23810015Speter#define MR2_1_STOP 0x07 23910015Speter#define MR2_2_STOP 0x0F 24010015Speter/* 24110015Speter * Clear to send automatic testing before character sent 24210015Speter */ 24310015Speter#define MR2_RTSCONT 0x10 24410015Speter/* 24510015Speter * Reset RTS automatically after sending character? 24610015Speter */ 24710015Speter#define MR2_CTSCONT 0x20 24810015Speter/* 24910015Speter * Channel mode 25010015Speter */ 25110015Speter#define MR2_NORMAL 0x00 25210015Speter#define MR2_AUTO 0x40 25310015Speter#define MR2_LOCAL 0x80 25410015Speter#define MR2_REMOTE 0xC0 25510015Speter 25610015Speter/* 25710015Speter * CLOCK SELECT REGISTER - this and the code assumes ispeed == ospeed 25810015Speter */ 25910015Speter/* 26010015Speter * Clocking rates are in lower and upper nibbles.. R = upper, T = lower 26110015Speter */ 26210015Speter#define CLK75 0x0 26310015Speter#define CLK110 0x1 /* 110 on XIO!! */ 26410015Speter#define CLK38400 0x2 /* out of sequence */ 26510015Speter#define CLK150 0x3 26610015Speter#define CLK300 0x4 26710015Speter#define CLK600 0x5 26810015Speter#define CLK1200 0x6 26910015Speter#define CLK2000 0x7 27010015Speter#define CLK2400 0x8 27110015Speter#define CLK4800 0x9 27210015Speter#define CLK7200 0xa /* unchecked */ 27310015Speter#define CLK9600 0xb 27410015Speter#define CLK19200 0xc 27510015Speter#define CLK57600 0xd 27610015Speter 27710015Speter/* 27810044Speter * Per-port (channel) soft information structure, stored in the driver. 27910015Speter * This is visible via ioctl()'s. 28010015Speter */ 28110015Speterstruct si_port { 28210015Speter volatile struct si_channel *sp_ccb; 28310015Speter struct tty *sp_tty; 28410015Speter int sp_pend; /* pending command */ 28510015Speter int sp_last_hi_ip; /* cached DCD */ 28610015Speter int sp_state; 28712174Speter int sp_delta_overflows; 28829676Sgibbs struct callout_handle lstart_ch;/* For canceling our timeout */ 28910015Speter int sp_debug; /* debug mask */ 290136058Sphk char sp_name[5]; 29110015Speter}; 29210015Speter 29310015Speter/* sp_state */ 294136058Sphk/* 0x0001 -- */ 29510015Speter/* 0x0002 -- */ 29610015Speter/* 0x0004 -- */ 29710015Speter/* 0x0008 -- */ 29810015Speter/* 0x0010 -- */ 29910015Speter/* 0x0020 -- */ 30010015Speter/* 0x0040 -- */ 30110015Speter/* 0x0080 -- */ 30210015Speter#define SS_LSTART 0x0100 /* lstart timeout pending */ 303179589Speter/* 0x0200 -- */ 304136058Sphk/* 0x0400 -- */ 30510015Speter/* 0x0800 -- */ 30610015Speter 30710015Speter/* 30810015Speter * Command post flags 30910015Speter */ 31010015Speter#define SI_NOWAIT 0x00 /* Don't wait for command */ 31110015Speter#define SI_WAIT 0x01 /* Wait for complete */ 31210015Speter 31310015Speter/* 31410015Speter * SI ioctls 31510015Speter */ 31610015Speter/* 31710015Speter * struct for use by Specialix ioctls - used by siconfig(8) 31810015Speter */ 31910015Spetertypedef struct { 32010015Speter unsigned char 32110015Speter sid_port:5, /* 0 - 31 ports per card */ 32210044Speter sid_card:2, /* 0 - 3 cards */ 32310044Speter sid_control:1; /* controlling device (all cards) */ 32410015Speter} sidev_t; 32510015Speterstruct si_tcsi { 32610015Speter sidev_t tc_dev; 32710015Speter union { 32810015Speter int x_int; 32910015Speter int x_dbglvl; 33010015Speter } tc_action; 33110015Speter#define tc_card tc_dev.sid_card 33210015Speter#define tc_port tc_dev.sid_port 33310015Speter#define tc_int tc_action.x_int 33410015Speter#define tc_dbglvl tc_action.x_dbglvl 33510015Speter}; 33610044Speter 33710044Speterstruct si_pstat { 33810044Speter sidev_t tc_dev; 33910044Speter union { 34010044Speter struct si_port x_siport; 34110044Speter struct si_channel x_ccb; 34210044Speter struct tty x_tty; 34310044Speter } tc_action; 34410044Speter#define tc_siport tc_action.x_siport 34510044Speter#define tc_ccb tc_action.x_ccb 34610044Speter#define tc_tty tc_action.x_tty 34710044Speter}; 34810044Speter 34910015Speter#define IOCTL_MIN 96 35010015Speter#define TCSIDEBUG _IOW('S', 96, struct si_tcsi) /* Toggle debug */ 35110015Speter#define TCSIRXIT _IOW('S', 97, struct si_tcsi) /* RX int throttle */ 35210015Speter#define TCSIIT _IOW('S', 98, struct si_tcsi) /* TX int throttle */ 35310044Speter /* 99 defunct */ 35410015Speter /* 100 defunct */ 35510015Speter /* 101 defunct */ 35610015Speter /* 102 defunct */ 35710015Speter /* 103 defunct */ 35810015Speter /* 104 defunct */ 35910015Speter#define TCSISTATE _IOWR('S', 105, struct si_tcsi) /* get current state of RTS 36010015Speter DCD and DTR pins */ 36112174Speter /* 106 defunct */ 36210015Speter#define TCSIPORTS _IOR('S', 107, int) /* Number of ports found */ 36310015Speter#define TCSISDBG_LEVEL _IOW('S', 108, struct si_tcsi) /* equivalent of TCSIDEBUG which sets a 36410015Speter * particular debug level (DBG_??? bit 36510015Speter * mask), default is 0xffff */ 36610015Speter#define TCSIGDBG_LEVEL _IOWR('S', 109, struct si_tcsi) 36710015Speter#define TCSIGRXIT _IOWR('S', 110, struct si_tcsi) 36810015Speter#define TCSIGIT _IOWR('S', 111, struct si_tcsi) 36910044Speter /* 112 defunct */ 37010015Speter /* 113 defunct */ 37110015Speter /* 114 defunct */ 37210015Speter /* 115 defunct */ 37310015Speter /* 116 defunct */ 37412174Speter /* 117 defunct */ 37510015Speter 37610015Speter#define TCSISDBG_ALL _IOW('S', 118, int) /* set global debug level */ 37710015Speter#define TCSIGDBG_ALL _IOR('S', 119, int) /* get global debug level */ 37810015Speter 37912174Speter /* 120 defunct */ 38010044Speter /* 121 defunct */ 38110044Speter /* 122 defunct */ 38212174Speter /* 123 defunct */ 38310015Speter#define TCSIMODULES _IOR('S', 124, int) /* Number of modules found */ 38410015Speter 38510044Speter/* Various stats and monitoring hooks per tty device */ 38610044Speter#define TCSI_PORT _IOWR('S', 125, struct si_pstat) /* get si_port */ 38710044Speter#define TCSI_CCB _IOWR('S', 126, struct si_pstat) /* get si_ccb */ 38810015Speter 38910044Speter#define IOCTL_MAX 127 39010044Speter 39110015Speter#define IS_SI_IOCTL(cmd) ((u_int)((cmd)&0xff00) == ('S'<<8) && \ 39210015Speter (u_int)((cmd)&0xff) >= IOCTL_MIN && \ 39310015Speter (u_int)((cmd)&0xff) <= IOCTL_MAX) 39410015Speter 39510015Speter#define CONTROLDEV "/dev/si_control" 396