aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/rio')
-rw-r--r--drivers/char/rio/Makefile12
-rw-r--r--drivers/char/rio/board.h143
-rw-r--r--drivers/char/rio/bootpkt.h62
-rw-r--r--drivers/char/rio/brates.h107
-rw-r--r--drivers/char/rio/chan.h33
-rw-r--r--drivers/char/rio/cirrus.h463
-rw-r--r--drivers/char/rio/cmd.h84
-rw-r--r--drivers/char/rio/cmdblk.h60
-rw-r--r--drivers/char/rio/cmdpkt.h206
-rw-r--r--drivers/char/rio/control.h62
-rw-r--r--drivers/char/rio/daemon.h334
-rw-r--r--drivers/char/rio/data.h40
-rw-r--r--drivers/char/rio/debug.h39
-rw-r--r--drivers/char/rio/defaults.h59
-rw-r--r--drivers/char/rio/eisa.h104
-rw-r--r--drivers/char/rio/enable.h50
-rw-r--r--drivers/char/rio/error.h85
-rw-r--r--drivers/char/rio/errors.h104
-rw-r--r--drivers/char/rio/formpkt.h154
-rw-r--r--drivers/char/rio/func.h154
-rw-r--r--drivers/char/rio/host.h134
-rw-r--r--drivers/char/rio/hosthw.h57
-rw-r--r--drivers/char/rio/link.h188
-rw-r--r--drivers/char/rio/linux_compat.h122
-rw-r--r--drivers/char/rio/list.h196
-rw-r--r--drivers/char/rio/lrt.h55
-rw-r--r--drivers/char/rio/ltt.h55
-rw-r--r--drivers/char/rio/lttwake.h53
-rw-r--r--drivers/char/rio/map.h103
-rw-r--r--drivers/char/rio/mca.h73
-rw-r--r--drivers/char/rio/mesg.h41
-rw-r--r--drivers/char/rio/param.h61
-rw-r--r--drivers/char/rio/parmmap.h96
-rw-r--r--drivers/char/rio/pci.h76
-rw-r--r--drivers/char/rio/phb.h293
-rw-r--r--drivers/char/rio/pkt.h120
-rw-r--r--drivers/char/rio/poll.h76
-rw-r--r--drivers/char/rio/port.h245
-rw-r--r--drivers/char/rio/proto.h244
-rw-r--r--drivers/char/rio/protsts.h119
-rw-r--r--drivers/char/rio/qbuf.h67
-rw-r--r--drivers/char/rio/rio.h294
-rw-r--r--drivers/char/rio/rio_linux.c1380
-rw-r--r--drivers/char/rio/rio_linux.h187
-rw-r--r--drivers/char/rio/rioboard.h281
-rw-r--r--drivers/char/rio/rioboot.c1360
-rw-r--r--drivers/char/rio/riocmd.c1041
-rw-r--r--drivers/char/rio/rioctrl.c1869
-rw-r--r--drivers/char/rio/riodrvr.h144
-rw-r--r--drivers/char/rio/rioinfo.h96
-rw-r--r--drivers/char/rio/rioinit.c1617
-rw-r--r--drivers/char/rio/riointr.c951
-rw-r--r--drivers/char/rio/rioioctl.h103
-rw-r--r--drivers/char/rio/riolocks.h43
-rw-r--r--drivers/char/rio/rioparam.c744
-rw-r--r--drivers/char/rio/riopcicopy.c8
-rw-r--r--drivers/char/rio/rioroute.c1238
-rw-r--r--drivers/char/rio/riospace.h161
-rw-r--r--drivers/char/rio/riotable.c1044
-rw-r--r--drivers/char/rio/riotime.h63
-rw-r--r--drivers/char/rio/riotty.c1376
-rw-r--r--drivers/char/rio/riotypes.h135
-rw-r--r--drivers/char/rio/riowinif.h1335
-rw-r--r--drivers/char/rio/riscos.h63
-rw-r--r--drivers/char/rio/rom.h64
-rw-r--r--drivers/char/rio/route.h108
-rw-r--r--drivers/char/rio/rtahw.h75
-rw-r--r--drivers/char/rio/rup.h82
-rw-r--r--drivers/char/rio/rupstat.h51
-rw-r--r--drivers/char/rio/sam.h74
-rw-r--r--drivers/char/rio/selftest.h73
-rw-r--r--drivers/char/rio/space.h45
-rw-r--r--drivers/char/rio/sysmap.h63
-rw-r--r--drivers/char/rio/timeouts.h51
-rw-r--r--drivers/char/rio/top.h49
-rw-r--r--drivers/char/rio/typdef.h82
-rw-r--r--drivers/char/rio/unixrup.h56
77 files changed, 21235 insertions, 0 deletions
diff --git a/drivers/char/rio/Makefile b/drivers/char/rio/Makefile
new file mode 100644
index 000000000000..bce2bd1204ed
--- /dev/null
+++ b/drivers/char/rio/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for the linux rio-subsystem.
3#
4# (C) R.E.Wolff@BitWizard.nl
5#
6# This file is GPL. See other files for the full Blurb. I'm lazy today.
7#
8
9obj-$(CONFIG_RIO) += rio.o
10
11rio-objs := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \
12 rioparam.o riopcicopy.o rioroute.o riotable.o riotty.o
diff --git a/drivers/char/rio/board.h b/drivers/char/rio/board.h
new file mode 100644
index 000000000000..0b397e1c8f1c
--- /dev/null
+++ b/drivers/char/rio/board.h
@@ -0,0 +1,143 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : board.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:07
26** Retrieved : 11/6/98 11:34:20
27**
28** ident @(#)board.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_board_h__
34#define __rio_board_h__
35
36#ifdef SCCS_LABELS
37static char *_board_h_sccs_ = "@(#)board.h 1.2";
38#endif
39
40/*
41** board.h contains the definitions for the *hardware* of the host cards.
42** It describes the memory overlay for the dual port RAM area.
43*/
44
45#define DP_SRAM1_SIZE 0x7C00
46#define DP_SRAM2_SIZE 0x0200
47#define DP_SRAM3_SIZE 0x7000
48#define DP_SCRATCH_SIZE 0x1000
49#define DP_PARMMAP_ADDR 0x01FE /* offset into SRAM2 */
50#define DP_STARTUP_ADDR 0x01F8 /* offset into SRAM2 */
51
52/*
53** The shape of the Host Control area, at offset 0x7C00, Write Only
54*/
55struct s_Ctrl
56{
57 BYTE DpCtl; /* 7C00 */
58 BYTE Dp_Unused2_[127];
59 BYTE DpIntSet; /* 7C80 */
60 BYTE Dp_Unused3_[127];
61 BYTE DpTpuReset; /* 7D00 */
62 BYTE Dp_Unused4_[127];
63 BYTE DpIntReset; /* 7D80 */
64 BYTE Dp_Unused5_[127];
65};
66
67/*
68** The PROM data area on the host (0x7C00), Read Only
69*/
70struct s_Prom
71{
72 WORD DpSlxCode[2];
73 WORD DpRev;
74 WORD Dp_Unused6_;
75 WORD DpUniq[4];
76 WORD DpJahre;
77 WORD DpWoche;
78 WORD DpHwFeature[5];
79 WORD DpOemId;
80 WORD DpSiggy[16];
81};
82
83/*
84** Union of the Ctrl and Prom areas
85*/
86union u_CtrlProm /* This is the control/PROM area (0x7C00) */
87{
88 struct s_Ctrl DpCtrl;
89 struct s_Prom DpProm;
90};
91
92/*
93** The top end of memory!
94*/
95struct s_ParmMapS /* Area containing Parm Map Pointer */
96{
97 BYTE Dp_Unused8_[DP_PARMMAP_ADDR];
98 WORD DpParmMapAd;
99};
100
101struct s_StartUpS
102{
103 BYTE Dp_Unused9_[DP_STARTUP_ADDR];
104 BYTE Dp_LongJump[0x4];
105 BYTE Dp_Unused10_[2];
106 BYTE Dp_ShortJump[0x2];
107};
108
109union u_Sram2ParmMap /* This is the top of memory (0x7E00-0x7FFF) */
110{
111 BYTE DpSramMem[DP_SRAM2_SIZE];
112 struct s_ParmMapS DpParmMapS;
113 struct s_StartUpS DpStartUpS;
114};
115
116/*
117** This is the DP RAM overlay.
118*/
119struct DpRam
120{
121 BYTE DpSram1[DP_SRAM1_SIZE]; /* 0000 - 7BFF */
122 union u_CtrlProm DpCtrlProm; /* 7C00 - 7DFF */
123 union u_Sram2ParmMap DpSram2ParmMap; /* 7E00 - 7FFF */
124 BYTE DpScratch[DP_SCRATCH_SIZE]; /* 8000 - 8FFF */
125 BYTE DpSram3[DP_SRAM3_SIZE]; /* 9000 - FFFF */
126};
127
128#define DpControl DpCtrlProm.DpCtrl.DpCtl
129#define DpSetInt DpCtrlProm.DpCtrl.DpIntSet
130#define DpResetTpu DpCtrlProm.DpCtrl.DpTpuReset
131#define DpResetInt DpCtrlProm.DpCtrl.DpIntReset
132
133#define DpSlx DpCtrlProm.DpProm.DpSlxCode
134#define DpRevision DpCtrlProm.DpProm.DpRev
135#define DpUnique DpCtrlProm.DpProm.DpUniq
136#define DpYear DpCtrlProm.DpProm.DpJahre
137#define DpWeek DpCtrlProm.DpProm.DpWoche
138#define DpSignature DpCtrlProm.DpProm.DpSiggy
139
140#define DpParmMapR DpSram2ParmMap.DpParmMapS.DpParmMapAd
141#define DpSram2 DpSram2ParmMap.DpSramMem
142
143#endif
diff --git a/drivers/char/rio/bootpkt.h b/drivers/char/rio/bootpkt.h
new file mode 100644
index 000000000000..c329aeb7c871
--- /dev/null
+++ b/drivers/char/rio/bootpkt.h
@@ -0,0 +1,62 @@
1
2
3/****************************************************************************
4 ******* *******
5 ******* B O O T P A C K E T H E A D E R F I L E
6 ******* *******
7 ****************************************************************************
8
9 Author : Ian Nandhra
10 Date :
11
12 *
13 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
29 Version : 0.01
30
31
32 Mods
33 ----------------------------------------------------------------------------
34 Date By Description
35 ----------------------------------------------------------------------------
36
37 ***************************************************************************/
38
39#ifndef _pkt_h
40#define _pkt_h 1
41
42#ifndef lint
43#ifdef SCCS
44static char *_rio_bootpkt_h_sccs = "@(#)bootpkt.h 1.1" ;
45#endif
46#endif
47
48 /*************************************************
49 * Overlayed onto the Data fields of a regular
50 * Packet
51 ************************************************/
52typedef struct BOOT_PKT BOOT_PKT ;
53struct BOOT_PKT {
54 short seq_num ;
55 char data[10] ;
56 } ;
57
58
59#endif
60
61/*********** end of file ***********/
62
diff --git a/drivers/char/rio/brates.h b/drivers/char/rio/brates.h
new file mode 100644
index 000000000000..bd4fc84ec6cf
--- /dev/null
+++ b/drivers/char/rio/brates.h
@@ -0,0 +1,107 @@
1/****************************************************************************
2 ******* *******
3 ******* BRATES.H *******
4 ******* *******
5 ****************************************************************************
6
7 Author : Jeremy Rolls
8 Date : 1 Nov 1990
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _brates_h
38#ifndef lint
39/* static char * _brates_h_sccs = "@(#)brates.h 1.4"; */
40#endif
41#define _brates_h 1
42/* List of baud rate defines. Most are borrowed from /usr/include/sys/termio.h
43*/
44#ifndef INKERNEL
45
46#define B0 0x00
47#define B50 0x01
48#define B75 0x02
49#define B110 0x03
50#define B134 0x04
51#define B150 0x05
52#define B200 0x06
53#define B300 0x07
54#define B600 0x08
55#define B1200 0x09
56#define B1800 0x0a
57#define B2400 0x0b
58#define B4800 0x0c
59#define B9600 0x0d
60#define B19200 0x0e
61#define B38400 0x0f
62
63#endif
64
65/*
66** The following baudrates may or may not be defined
67** on various UNIX systems.
68** If they are not then we define them.
69** If they are then we do not define them ;-)
70**
71** This is appalling that we use same definitions as UNIX
72** for our own download code as there is no garuntee that
73** B57600 will be defined as 0x11 by a UNIX system....
74** Arghhhhh!!!!!!!!!!!!!!
75*/
76#if !defined(B56000)
77#define B56000 0x10
78#endif
79
80#if !defined(B57600)
81#define B57600 0x11
82#endif
83
84#if !defined(B64000)
85#define B64000 0x12
86#endif
87
88#if !defined(B115200)
89#define B115200 0x13
90#endif
91
92
93#if !defined(B2000)
94#define B2000 0x14
95#endif
96
97
98#define MAX_RATE B2000
99
100struct baud_rate /* Tag for baud rates */
101{
102 /* short host_rate,*/ /* As passed by the driver */
103 short divisor, /* The divisor */
104 prescaler; /* The pre-scaler */
105};
106
107#endif
diff --git a/drivers/char/rio/chan.h b/drivers/char/rio/chan.h
new file mode 100644
index 000000000000..5b306543328f
--- /dev/null
+++ b/drivers/char/rio/chan.h
@@ -0,0 +1,33 @@
1/*
2 *
3 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19#ifndef _chan_h
20#define _chan_h
21
22#ifndef lint
23#ifdef SCCS
24static char *_rio_chan_h_sccs = "@(#)chan.h 1.1" ;
25#endif
26#endif
27
28#define Link0 0
29#define Link1 1
30#define Link2 2
31#define Link3 3
32
33#endif
diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h
new file mode 100644
index 000000000000..cf056a990f18
--- /dev/null
+++ b/drivers/char/rio/cirrus.h
@@ -0,0 +1,463 @@
1/****************************************************************************
2 ******* *******
3 ******* CIRRUS.H *******
4 ******* *******
5 ****************************************************************************
6
7 Author : Jeremy Rolls
8 Date : 3 Aug 1990
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _cirrus_h
38#ifndef lint
39/* static char* _cirrus_h_sccs = "@(#)cirrus.h 1.16"; */
40#endif
41#define _cirrus_h 1
42
43#ifdef RTA
44#define TO_UART RX
45#define TO_DRIVER TX
46#endif
47
48#ifdef HOST
49#define TO_UART TX
50#define TO_DRIVER RX
51#endif
52#ifdef RTA
53/* Miscellaneous defines for CIRRUS addresses and related logic for
54 interrupts etc.
55*/
56#define MAP(a) ((short *)(cirrus_base + (a)))
57#define outp(a,b) (*MAP (a) =(b))
58#define inp(a) ((*MAP (a)) & 0xff)
59#define CIRRUS_FIRST (short*)0x7300
60#define CIRRUS_SECOND (short*)0x7200
61#define CIRRUS_THIRD (short*)0x7100
62#define CIRRUS_FOURTH (short*)0x7000
63#define PORTS_ON_CIRRUS 4
64#define CIRRUS_FIFO_SIZE 12
65#define SPACE 0x20
66#define TAB 0x09
67#define LINE_FEED 0x0a
68#define CARRIAGE_RETURN 0x0d
69#define BACKSPACE 0x08
70#define SPACES_IN_TABS 8
71#define SEND_ESCAPE 0x00
72#define START_BREAK 0x81
73#define TIMER_TICK 0x82
74#define STOP_BREAK 0x83
75#define BASE(a) ((a) < 4 ? (short*)CIRRUS_FIRST : ((a) < 8 ? (short *)CIRRUS_SECOND : ((a) < 12 ? (short*)CIRRUS_THIRD : (short *)CIRRUS_FOURTH)))
76#define txack1 ((short *)0x7104)
77#define rxack1 ((short *)0x7102)
78#define mdack1 ((short *)0x7106)
79#define txack2 ((short *)0x7006)
80#define rxack2 ((short *)0x7004)
81#define mdack2 ((short *)0x7100)
82#define int_latch ((short *) 0x7800)
83#define int_status ((short *) 0x7c00)
84#define tx1_pending 0x20
85#define rx1_pending 0x10
86#define md1_pending 0x40
87#define tx2_pending 0x02
88#define rx2_pending 0x01
89#define md2_pending 0x40
90#define module1_bits 0x07
91#define module1_modern 0x08
92#define module2_bits 0x70
93#define module2_modern 0x80
94#define module_blank 0xf
95#define rs232_d25 0x0
96#define rs232_rj45 0x1
97#define rs422_d25 0x3
98#define parallel 0x5
99
100#define CLK0 0x00
101#define CLK1 0x01
102#define CLK2 0x02
103#define CLK3 0x03
104#define CLK4 0x04
105
106#define CIRRUS_REVC 0x42
107#define CIRRUS_REVE 0x44
108
109#define TURNON 1
110#define TURNOFF 0
111
112/* The list of CIRRUS registers.
113 NB. These registers are relative values on 8 bit boundaries whereas
114 on the RTA's the CIRRUS registers are on word boundaries. Use pointer
115 arithmetic (short *) to obtain the real addresses required */
116#define ccr 0x05 /* Channel Command Register */
117#define ier 0x06 /* Interrupt Enable Register */
118#define cor1 0x08 /* Channel Option Register 1 */
119#define cor2 0x09 /* Channel Option Register 2 */
120#define cor3 0x0a /* Channel Option Register 3 */
121#define cor4 0x1e /* Channel Option Register 4 */
122#define cor5 0x1f /* Channel Option Register 5 */
123
124#define ccsr 0x0b /* Channel Control Status Register */
125#define rdcr 0x0e /* Receive Data Count Register */
126#define tdcr 0x12 /* Transmit Data Count Register */
127#define mcor1 0x15 /* Modem Change Option Register 1 */
128#define mcor2 0x16 /* Modem Change Option Regsiter 2 */
129
130#define livr 0x18 /* Local Interrupt Vector Register */
131#define schr1 0x1a /* Special Character Register 1 */
132#define schr2 0x1b /* Special Character Register 2 */
133#define schr3 0x1c /* Special Character Register 3 */
134#define schr4 0x1d /* Special Character Register 4 */
135
136#define rtr 0x20 /* Receive Timer Register */
137#define rtpr 0x21 /* Receive Timeout Period Register */
138#define lnc 0x24 /* Lnext character */
139
140#define rivr 0x43 /* Receive Interrupt Vector Register */
141#define tivr 0x42 /* Transmit Interrupt Vector Register */
142#define mivr 0x41 /* Modem Interrupt Vector Register */
143#define gfrcr 0x40 /* Global Firmware Revision code Reg */
144#define ricr 0x44 /* Receive Interrupting Channel Reg */
145#define ticr 0x45 /* Transmit Interrupting Channel Reg */
146#define micr 0x46 /* Modem Interrupting Channel Register */
147
148#define gcr 0x4b /* Global configuration register*/
149#define misr 0x4c /* Modem interrupt status register */
150
151#define rbusr 0x59
152#define tbusr 0x5a
153#define mbusr 0x5b
154
155#define eoir 0x60 /* End Of Interrupt Register */
156#define rdsr 0x62 /* Receive Data / Status Register */
157#define tdr 0x63 /* Transmit Data Register */
158#define svrr 0x67 /* Service Request Register */
159
160#define car 0x68 /* Channel Access Register */
161#define mir 0x69 /* Modem Interrupt Register */
162#define tir 0x6a /* Transmit Interrupt Register */
163#define rir 0x6b /* Receive Interrupt Register */
164#define msvr1 0x6c /* Modem Signal Value Register 1 */
165#define msvr2 0x6d /* Modem Signal Value Register 2*/
166#define psvr 0x6f /* Printer Signal Value Register*/
167
168#define tbpr 0x72 /* Transmit Baud Rate Period Register */
169#define tcor 0x76 /* Transmit Clock Option Register */
170
171#define rbpr 0x78 /* Receive Baud Rate Period Register */
172#define rber 0x7a /* Receive Baud Rate Extension Register */
173#define rcor 0x7c /* Receive Clock Option Register*/
174#define ppr 0x7e /* Prescalar Period Register */
175
176/* Misc registers used for forcing the 1400 out of its reset woes */
177#define airl 0x6d
178#define airm 0x6e
179#define airh 0x6f
180#define btcr 0x66
181#define mtcr 0x6c
182#define tber 0x74
183
184#endif /* #ifdef RTA */
185
186
187/* Bit fields for particular registers */
188
189/* GCR */
190#define GCR_SERIAL 0x00 /* Configure as serial channel */
191#define GCR_PARALLEL 0x80 /* Configure as parallel channel */
192
193/* RDSR - when status read from FIFO */
194#define RDSR_BREAK 0x08 /* Break received */
195#define RDSR_TIMEOUT 0x80 /* No new data timeout */
196#define RDSR_SC1 0x10 /* Special char 1 (tx XON) matched */
197#define RDSR_SC2 0x20 /* Special char 2 (tx XOFF) matched */
198#define RDSR_SC12_MASK 0x30 /* Mask for special chars 1 and 2 */
199
200/* PPR */
201#define PPR_DEFAULT 0x31 /* Default value - for a 25Mhz clock gives
202 a timeout period of 1ms */
203
204/* LIVR */
205#define LIVR_EXCEPTION 0x07 /* Receive exception interrupt */
206
207/* CCR */
208#define CCR_RESET 0x80 /* Reset channel */
209#define CCR_CHANGE 0x4e /* COR's have changed - NB always change all
210 COR's */
211#define CCR_WFLUSH 0x82 /* Flush transmit FIFO and TSR / THR */
212
213#define CCR_SENDSC1 0x21 /* Send special character one */
214#define CCR_SENDSC2 0x22 /* Send special character two */
215#define CCR_SENDSC3 0x23 /* Send special character three */
216#define CCR_SENDSC4 0x24 /* Send special character four */
217
218#define CCR_TENABLE 0x18 /* Enable transmitter */
219#define CCR_TDISABLE 0x14 /* Disable transmitter */
220#define CCR_RENABLE 0x12 /* Enable receiver */
221#define CCR_RDISABLE 0x11 /* Disable receiver */
222
223#define CCR_READY 0x00 /* CCR is ready for another command */
224
225/* CCSR */
226#define CCSR_TXENABLE 0x08 /* Transmitter enable */
227#define CCSR_RXENABLE 0x80 /* Receiver enable */
228#define CCSR_TXFLOWOFF 0x04 /* Transmit flow off */
229#define CCSR_TXFLOWON 0x02 /* Transmit flow on */
230
231/* SVRR */
232#define SVRR_RECEIVE 0x01 /* Receive interrupt pending */
233#define SVRR_TRANSMIT 0x02 /* Transmit interrupt pending */
234#define SVRR_MODEM 0x04 /* Modem interrupt pending */
235
236/* CAR */
237#define CAR_PORTS 0x03 /* Bit fields for ports */
238
239/* IER */
240#define IER_MODEM 0x80 /* Change in modem status */
241#define IER_RECEIVE 0x10 /* Good data / data exception */
242#define IER_TRANSMITR 0x04 /* Transmit ready (FIFO empty) */
243#define IER_TRANSMITE 0x02 /* Transmit empty */
244#define IER_TIMEOUT 0x01 /* Timeout on no data */
245
246#define IER_DEFAULT 0x94 /* Default values */
247#define IER_PARALLEL 0x84 /* Default for Parallel */
248#define IER_EMPTY 0x92 /* Transmitter empty rather than ready */
249
250/* COR1 - Driver only */
251#define COR1_INPCK 0x10 /* Check parity of received characters */
252
253/* COR1 - driver and RTA */
254#define COR1_ODD 0x80 /* Odd parity */
255#define COR1_EVEN 0x00 /* Even parity */
256#define COR1_NOP 0x00 /* No parity */
257#define COR1_FORCE 0x20 /* Force parity */
258#define COR1_NORMAL 0x40 /* With parity */
259#define COR1_1STOP 0x00 /* 1 stop bit */
260#define COR1_15STOP 0x04 /* 1.5 stop bits */
261#define COR1_2STOP 0x08 /* 2 stop bits */
262#define COR1_5BITS 0x00 /* 5 data bits */
263#define COR1_6BITS 0x01 /* 6 data bits */
264#define COR1_7BITS 0x02 /* 7 data bits */
265#define COR1_8BITS 0x03 /* 8 data bits */
266
267#define COR1_HOST 0xef /* Safe host bits */
268
269/* RTA only */
270#define COR1_CINPCK 0x00 /* Check parity of received characters */
271#define COR1_CNINPCK 0x10 /* Don't check parity */
272
273/* COR2 bits for both RTA and driver use */
274#define COR2_IXANY 0x80 /* IXANY - any character is XON */
275#define COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */
276#define COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */
277
278/* Additional driver bits */
279#define COR2_HUPCL 0x20 /* Hang up on close */
280#define COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */
281#define COR2_IXOFF 0x01 /* Enable rx software flow control */
282#define COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */
283
284/* RTA use only */
285#define COR2_ETC 0x20 /* Embedded transmit options */
286#define COR2_LOCAL 0x10 /* Local loopback mode */
287#define COR2_REMOTE 0x08 /* Remote loopback mode */
288#define COR2_HOST 0xc2 /* Safe host bits */
289
290/* COR3 - RTA use only */
291#define COR3_SCDRNG 0x80 /* Enable special char detect for range */
292#define COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */
293#define COR3_FCT 0x20 /* Flow control transparency */
294#define COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */
295#define COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */
296#define COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */
297#define COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */
298#define COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */
299
300#define COR3_THRESHOLD COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */
301
302#define COR3_DEFAULT (COR3_FCT | COR3_THRESHOLD)
303 /* Default bits for COR3 */
304
305/* COR4 driver and RTA use */
306#define COR4_IGNCR 0x80 /* Throw away CR's on input */
307#define COR4_ICRNL 0x40 /* Map CR -> NL on input */
308#define COR4_INLCR 0x20 /* Map NL -> CR on input */
309#define COR4_IGNBRK 0x10 /* Ignore Break */
310#define COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */
311#define COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */
312
313
314/* COR4 driver only */
315#define COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */
316#define COR4_PARMRK 0x02 /* PARMRK */
317
318#define COR4_HOST 0xf8 /* Safe host bits */
319
320/* COR4 RTA only */
321#define COR4_CIGNPAR 0x02 /* Thrown away bad characters */
322#define COR4_CPARMRK 0x04 /* PARMRK characters */
323#define COR4_CNPARMRK 0x03 /* Don't PARMRK */
324
325/* COR5 driver and RTA use */
326#define COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */
327#define COR5_LNE 0x40 /* Enable LNEXT processing */
328#define COR5_CMOE 0x20 /* Match good and errored characters */
329#define COR5_ONLCR 0x02 /* NL -> CR NL on output */
330#define COR5_OCRNL 0x01 /* CR -> NL on output */
331
332/*
333** Spare bits - these are not used in the CIRRUS registers, so we use
334** them to set various other features.
335*/
336/*
337** tstop and tbusy indication
338*/
339#define COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */
340#define COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */
341/*
342** TAB3
343*/
344#define COR5_TAB3 0x10 /* TAB3 mode */
345
346#define COR5_HOST 0xc3 /* Safe host bits */
347
348/* CCSR */
349#define CCSR_TXFLOFF 0x04 /* Tx is xoffed */
350
351/* MSVR1 */
352/* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the
353 RTA. This is because otherwise DCD would get lost on the 1 parallel / 3
354 serial option.
355*/
356#define MSVR1_CD 0x80 /* CD (DSR on Cirrus) */
357#define MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */
358#define MSVR1_RI 0x20 /* RI */
359#define MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */
360#define MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */
361/* Next two used to indicate state of tbusy and tstop to driver */
362#define MSVR1_TSTOP 0x08 /* Set if port flow controlled */
363#define MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */
364
365#define MSVR1_HOST 0xf3 /* The bits the host wants */
366
367/* MSVR2 */
368#define MSVR2_DSR 0x02 /* DSR output pin (DTR on Cirrus) */
369
370/* MCOR */
371#define MCOR_CD 0x80 /* CD (DSR on Cirrus) */
372#define MCOR_RTS 0x40 /* RTS (CTS on Cirrus) */
373#define MCOR_RI 0x20 /* RI */
374#define MCOR_DTR 0x10 /* DTR (CD on Cirrus) */
375
376#define MCOR_DEFAULT (MCOR_CD | MCOR_RTS | MCOR_RI | MCOR_DTR)
377#define MCOR_FULLMODEM MCOR_DEFAULT
378#define MCOR_RJ45 (MCOR_CD | MCOR_RTS | MCOR_DTR)
379#define MCOR_RESTRICTED (MCOR_CD | MCOR_RTS)
380
381/* More MCOR - H/W Handshake (flowcontrol) stuff */
382#define MCOR_THRESH8 0x08 /* eight characters then we stop */
383#define MCOR_THRESH9 0x09 /* nine characters then we stop */
384#define MCOR_THRESH10 0x0A /* ten characters then we stop */
385#define MCOR_THRESH11 0x0B /* eleven characters then we stop */
386
387#define MCOR_THRESHBITS 0x0F /* mask for ANDing out the above */
388
389#define MCOR_THRESHOLD MCOR_THRESH9 /* MUST BE GREATER THAN COR3_THRESHOLD */
390
391
392/* RTPR */
393#define RTPR_DEFAULT 0x02 /* Default */
394
395
396/* Defines for the subscripts of a CONFIG packet */
397#define CONFIG_COR1 1 /* Option register 1 */
398#define CONFIG_COR2 2 /* Option register 2 */
399#define CONFIG_COR4 3 /* Option register 4 */
400#define CONFIG_COR5 4 /* Option register 5 */
401#define CONFIG_TXXON 5 /* Tx XON character */
402#define CONFIG_TXXOFF 6 /* Tx XOFF character */
403#define CONFIG_RXXON 7 /* Rx XON character */
404#define CONFIG_RXXOFF 8 /* Rx XOFF character */
405#define CONFIG_LNEXT 9 /* LNEXT character */
406#define CONFIG_TXBAUD 10 /* Tx baud rate */
407#define CONFIG_RXBAUD 11 /* Rx baud rate */
408
409/* Port status stuff */
410#define IDLE_CLOSED 0 /* Closed */
411#define IDLE_OPEN 1 /* Idle open */
412#define IDLE_BREAK 2 /* Idle on break */
413
414/* Subscript of MODEM STATUS packet */
415#define MODEM_VALUE 3 /* Current values of handshake pins */
416/* Subscript of SBREAK packet */
417#define BREAK_LENGTH 1 /* Length of a break in slices of 0.01 seconds
418 0 = stay on break until an EBREAK command
419 is sent */
420
421
422#define PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */
423
424/* Packet types going from Host to remote - with the exception of OPEN, MOPEN,
425 CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not
426 be used
427*/
428#define OPEN 0x00 /* Open a port */
429#define CONFIG 0x01 /* Configure a port */
430#define MOPEN 0x02 /* Modem open (block for DCD) */
431#define CLOSE 0x03 /* Close a port */
432#define WFLUSH (0x04 | PRE_EMPTIVE) /* Write flush */
433#define RFLUSH (0x05 | PRE_EMPTIVE) /* Read flush */
434#define RESUME (0x06 | PRE_EMPTIVE) /* Resume if xoffed */
435#define SBREAK 0x07 /* Start break */
436#define EBREAK 0x08 /* End break */
437#define SUSPEND (0x09 | PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */
438#define FCLOSE (0x0a | PRE_EMPTIVE) /* Force close */
439#define XPRINT 0x0b /* Xprint packet */
440#define MBIS (0x0c | PRE_EMPTIVE) /* Set modem lines */
441#define MBIC (0x0d | PRE_EMPTIVE) /* Clear modem lines */
442#define MSET (0x0e | PRE_EMPTIVE) /* Set modem lines */
443#define PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */
444#define MGET (0x10 | PRE_EMPTIVE) /* Force update of modem status */
445#define MEMDUMP (0x11 | PRE_EMPTIVE) /* Send back mem from addr supplied */
446#define READ_REGISTER (0x12 | PRE_EMPTIVE) /* Read CD1400 register (debug) */
447
448/* "Command" packets going from remote to host COMPLETE and MODEM_STATUS
449 use data[4] / data[3] to indicate current state and modem status respectively
450*/
451
452#define COMPLETE (0x20 | PRE_EMPTIVE)
453 /* Command complete */
454#define BREAK_RECEIVED (0x21 | PRE_EMPTIVE)
455 /* Break received */
456#define MODEM_STATUS (0x22 | PRE_EMPTIVE)
457 /* Change in modem status */
458
459/* "Command" packet that could go either way - handshake wake-up */
460#define HANDSHAKE (0x23 | PRE_EMPTIVE)
461 /* Wake-up to HOST / RTA */
462
463#endif
diff --git a/drivers/char/rio/cmd.h b/drivers/char/rio/cmd.h
new file mode 100644
index 000000000000..c369edaea2b3
--- /dev/null
+++ b/drivers/char/rio/cmd.h
@@ -0,0 +1,84 @@
1
2
3/****************************************************************************
4 ******* *******
5 ******* C O M M A N D P A C K E T H E A D E R S
6 ******* *******
7 ****************************************************************************
8
9 Author : Ian Nandhra
10 Date :
11
12 *
13 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
29 Version : 0.01
30
31
32 Mods
33 ----------------------------------------------------------------------------
34 Date By Description
35 ----------------------------------------------------------------------------
36
37 ***************************************************************************/
38
39
40#ifndef _cmd_h
41#define _cmd_h
42
43#ifndef lint
44#ifdef SCCS
45static char *_rio_cmd_h_sccs = "@(#)cmd.h 1.1" ;
46#endif
47#endif
48
49
50#define PRE_EMPTIVE_CMD 0x80
51#define INLINE_CMD ~PRE_EMPTIVE_CMD
52
53#define CMD_IGNORE_PKT ( (ushort) 0)
54#define CMD_STATUS_REQ ( (ushort) 1)
55#define CMD_UNIT_STATUS_REQ ( (ushort) 2) /* Is this needed ??? */
56#define CMD_CONF_PORT ( (ushort) 3)
57#define CMD_CONF_UNIT ( (ushort) 4)
58#define CMD_ROUTE_MAP_REQ ( (ushort) 5)
59#define CMD_FLUSH_TX ( (ushort) 6)
60#define CMD_FLUSH_RX ( (ushort) 7)
61#define CMD_PARTION_PORT ( (ushort) 8)
62#define CMD_RESET_PORT ( (ushort) 0x0a)
63#define CMD_BOOT_UNIT ( (ushort) 0x0b)
64#define CMD_FOUND_UNIT ( (ushort) 0x0c)
65#define CMD_ATTACHED_RTA_2 ( (ushort) 0x0d)
66#define CMD_PROVIDE_BOOT ( (ushort) 0x0e)
67#define CMD_CIRRUS ( (ushort) 0x0f)
68
69#define FORM_STATUS_PKT ( (ushort) 1 )
70#define FORM_POLL_PKT ( (ushort) 2 )
71#define FORM_LINK_STATUS_PKT ( (ushort) 3 )
72
73
74#define CMD_DATA_PORT ( (ushort) 1 )
75#define CMD_DATA ( (ushort) 2 )
76
77#define CMD_TX_PART ( (ushort) 2 )
78#define CMD_RX_PART ( (ushort) 3 )
79#define CMD_RX_LIMIT ( (ushort) 4 )
80
81#endif
82
83/*********** end of file ***********/
84
diff --git a/drivers/char/rio/cmdblk.h b/drivers/char/rio/cmdblk.h
new file mode 100644
index 000000000000..2b8efbdbee1c
--- /dev/null
+++ b/drivers/char/rio/cmdblk.h
@@ -0,0 +1,60 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : cmdblk.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:09
26** Retrieved : 11/6/98 11:34:20
27**
28** ident @(#)cmdblk.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_cmdblk_h__
34#define __rio_cmdblk_h__
35
36#ifdef SCCS_LABELS
37#ifndef lint
38static char *_cmdblk_h_sccs_ = "@(#)cmdblk.h 1.2";
39#endif
40#endif
41
42/*
43** the structure of a command block, used to queue commands destined for
44** a rup.
45*/
46
47struct CmdBlk
48{
49 struct CmdBlk *NextP; /* Pointer to next command block */
50 struct PKT Packet; /* A packet, to copy to the rup */
51 /* The func to call to check if OK */
52 int (*PreFuncP)(int, struct CmdBlk *);
53 int PreArg; /* The arg for the func */
54 /* The func to call when completed */
55 int (*PostFuncP)(int, struct CmdBlk *);
56 int PostArg; /* The arg for the func */
57};
58
59#define NUM_RIO_CMD_BLKS (3 * (MAX_RUP * 4 + LINKS_PER_UNIT * 4))
60#endif
diff --git a/drivers/char/rio/cmdpkt.h b/drivers/char/rio/cmdpkt.h
new file mode 100644
index 000000000000..46befd354f20
--- /dev/null
+++ b/drivers/char/rio/cmdpkt.h
@@ -0,0 +1,206 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : cmdpkt.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:09
26** Retrieved : 11/6/98 11:34:20
27**
28** ident @(#)cmdpkt.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32#ifndef __rio_cmdpkt_h__
33#define __rio_cmdpkt_h__
34
35#ifdef SCCS_LABELS
36#ifndef lint
37static char *_cmdpkt_h_sccs_ = "@(#)cmdpkt.h 1.2";
38#endif
39#endif
40
41/*
42** overlays for the data area of a packet. Used in both directions
43** (to build a packet to send, and to interpret a packet that arrives)
44** and is very inconvenient for MIPS, so they appear as two separate
45** structures - those used for modifying/reading packets on the card
46** and those for modifying/reading packets in real memory, which have an _M
47** suffix.
48*/
49
50#define RTA_BOOT_DATA_SIZE (PKT_MAX_DATA_LEN-2)
51
52/*
53** The boot information packet looks like this:
54** This structure overlays a PktCmd->CmdData structure, and so starts
55** at Data[2] in the actual pkt!
56*/
57struct BootSequence
58{
59 WORD NumPackets;
60 WORD LoadBase;
61 WORD CodeSize;
62};
63
64#define BOOT_SEQUENCE_LEN 8
65
66struct SamTop
67{
68 BYTE Unit;
69 BYTE Link;
70};
71
72struct CmdHdr
73{
74 BYTE PcCommand;
75 union
76 {
77 BYTE PcPhbNum;
78 BYTE PcLinkNum;
79 BYTE PcIDNum;
80 } U0;
81};
82
83
84struct PktCmd
85{
86 union
87 {
88 struct
89 {
90 struct CmdHdr CmdHdr;
91 struct BootSequence PcBootSequence;
92 } S1;
93 struct
94 {
95 WORD PcSequence;
96 BYTE PcBootData[RTA_BOOT_DATA_SIZE];
97 } S2;
98 struct
99 {
100 WORD __crud__;
101 BYTE PcUniqNum[4]; /* this is really a uint. */
102 BYTE PcModuleTypes; /* what modules are fitted */
103 } S3;
104 struct
105 {
106 struct CmdHdr CmdHdr;
107 BYTE __undefined__;
108 BYTE PcModemStatus;
109 BYTE PcPortStatus;
110 BYTE PcSubCommand; /* commands like mem or register dump */
111 WORD PcSubAddr; /* Address for command */
112 BYTE PcSubData[64]; /* Date area for command */
113 } S4;
114 struct
115 {
116 struct CmdHdr CmdHdr;
117 BYTE PcCommandText[1];
118 BYTE __crud__[20];
119 BYTE PcIDNum2; /* It had to go somewhere! */
120 } S5;
121 struct
122 {
123 struct CmdHdr CmdHdr;
124 struct SamTop Topology[LINKS_PER_UNIT];
125 } S6;
126 } U1;
127};
128
129struct PktCmd_M
130{
131 union
132 {
133 struct
134 {
135 struct
136 {
137 uchar PcCommand;
138 union
139 {
140 uchar PcPhbNum;
141 uchar PcLinkNum;
142 uchar PcIDNum;
143 } U0;
144 } CmdHdr;
145 struct
146 {
147 ushort NumPackets;
148 ushort LoadBase;
149 ushort CodeSize;
150 } PcBootSequence;
151 } S1;
152 struct
153 {
154 ushort PcSequence;
155 uchar PcBootData[RTA_BOOT_DATA_SIZE];
156 } S2;
157 struct
158 {
159 ushort __crud__;
160 uchar PcUniqNum[4]; /* this is really a uint. */
161 uchar PcModuleTypes; /* what modules are fitted */
162 } S3;
163 struct
164 {
165 ushort __cmd_hdr__;
166 uchar __undefined__;
167 uchar PcModemStatus;
168 uchar PcPortStatus;
169 uchar PcSubCommand;
170 ushort PcSubAddr;
171 uchar PcSubData[64];
172 } S4;
173 struct
174 {
175 ushort __cmd_hdr__;
176 uchar PcCommandText[1];
177 uchar __crud__[20];
178 uchar PcIDNum2; /* Tacked on end */
179 } S5;
180 struct
181 {
182 ushort __cmd_hdr__;
183 struct Top Topology[LINKS_PER_UNIT];
184 } S6;
185 } U1;
186};
187
188#define Command U1.S1.CmdHdr.PcCommand
189#define PhbNum U1.S1.CmdHdr.U0.PcPhbNum
190#define IDNum U1.S1.CmdHdr.U0.PcIDNum
191#define IDNum2 U1.S5.PcIDNum2
192#define LinkNum U1.S1.CmdHdr.U0.PcLinkNum
193#define Sequence U1.S2.PcSequence
194#define BootData U1.S2.PcBootData
195#define BootSequence U1.S1.PcBootSequence
196#define UniqNum U1.S3.PcUniqNum
197#define ModemStatus U1.S4.PcModemStatus
198#define PortStatus U1.S4.PcPortStatus
199#define SubCommand U1.S4.PcSubCommand
200#define SubAddr U1.S4.PcSubAddr
201#define SubData U1.S4.PcSubData
202#define CommandText U1.S5.PcCommandText
203#define RouteTopology U1.S6.Topology
204#define ModuleTypes U1.S3.PcModuleTypes
205
206#endif
diff --git a/drivers/char/rio/control.h b/drivers/char/rio/control.h
new file mode 100644
index 000000000000..1712f6261dd1
--- /dev/null
+++ b/drivers/char/rio/control.h
@@ -0,0 +1,62 @@
1
2
3/****************************************************************************
4 ******* *******
5 ******* C O N T R O L P A C K E T H E A D E R S
6 ******* *******
7 ****************************************************************************
8
9 Author : Jon Brawn
10 Date :
11
12 *
13 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
29 Version : 0.01
30
31
32 Mods
33 ----------------------------------------------------------------------------
34 Date By Description
35 ----------------------------------------------------------------------------
36
37 ***************************************************************************/
38
39
40#ifndef _control_h
41#define _control_h
42
43#ifndef lint
44/* static char *_rio_control_h_sccs = "@(#)control.h 1.4"; */
45#endif
46
47#define CONTROL '^'
48#define IFOAD ( CONTROL + 1 )
49#define IDENTIFY ( CONTROL + 2 )
50#define ZOMBIE ( CONTROL + 3 )
51#define UFOAD ( CONTROL + 4 )
52#define IWAIT ( CONTROL + 5 )
53
54#define IFOAD_MAGIC 0xF0AD /* of course */
55#define ZOMBIE_MAGIC (~0xDEAD) /* not dead -> zombie */
56#define UFOAD_MAGIC 0xD1E /* kill-your-neighbour */
57#define IWAIT_MAGIC 0xB1DE /* Bide your time */
58
59#endif
60
61/*********** end of file ***********/
62
diff --git a/drivers/char/rio/daemon.h b/drivers/char/rio/daemon.h
new file mode 100644
index 000000000000..62dba0e68b3e
--- /dev/null
+++ b/drivers/char/rio/daemon.h
@@ -0,0 +1,334 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : daemon.h
24** SID : 1.3
25** Last Modified : 11/6/98 11:34:09
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)daemon.h 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_daemon_h__
34#define __rio_daemon_h__
35
36#ifdef SCCS_LABELS
37#ifndef lint
38static char *_daemon_h_sccs_ = "@(#)daemon.h 1.3";
39#endif
40#endif
41
42
43/*
44** structures used on /dev/rio
45*/
46
47struct Error
48{
49 uint Error;
50 uint Entry;
51 uint Other;
52};
53
54struct DownLoad
55{
56 char *DataP;
57 uint Count;
58 uint ProductCode;
59};
60
61/*
62** A few constants....
63*/
64#ifndef MAX_VERSION_LEN
65#define MAX_VERSION_LEN 256
66#endif
67
68#ifndef MAX_XP_CTRL_LEN
69#define MAX_XP_CTRL_LEN 16 /* ALSO IN PORT.H */
70#endif
71
72struct PortSetup
73{
74 uint From; /* Set/Clear XP & IXANY Control from this port.... */
75 uint To; /* .... to this port */
76 uint XpCps; /* at this speed */
77 char XpOn[MAX_XP_CTRL_LEN]; /* this is the start string */
78 char XpOff[MAX_XP_CTRL_LEN]; /* this is the stop string */
79 uchar IxAny; /* enable/disable IXANY */
80 uchar IxOn; /* enable/disable IXON */
81 uchar Lock; /* lock port params */
82 uchar Store; /* store params across closes */
83 uchar Drain; /* close only when drained */
84};
85
86struct LpbReq
87{
88 uint Host;
89 uint Link;
90 struct LPB *LpbP;
91};
92
93struct RupReq
94{
95 uint HostNum;
96 uint RupNum;
97 struct RUP *RupP;
98};
99
100struct PortReq
101{
102 uint SysPort;
103 struct Port *PortP;
104};
105
106struct StreamInfo
107{
108 uint SysPort;
109#if 0
110 queue_t RQueue;
111 queue_t WQueue;
112#else
113 int RQueue;
114 int WQueue;
115#endif
116};
117
118struct HostReq
119{
120 uint HostNum;
121 struct Host *HostP;
122};
123
124struct HostDpRam
125{
126 uint HostNum;
127 struct DpRam *DpRamP;
128};
129
130struct DebugCtrl
131{
132 uint SysPort;
133 uint Debug;
134 uint Wait;
135};
136
137struct MapInfo
138{
139 uint FirstPort; /* 8 ports, starting from this (tty) number */
140 uint RtaUnique; /* reside on this RTA (unique number) */
141};
142
143struct MapIn
144{
145 uint NumEntries; /* How many port sets are we mapping? */
146 struct MapInfo *MapInfoP; /* Pointer to (user space) info */
147};
148
149struct SendPack
150{
151 unsigned int PortNum;
152 unsigned char Len;
153 unsigned char Data[PKT_MAX_DATA_LEN];
154};
155
156struct SpecialRupCmd
157{
158 struct PKT Packet;
159 unsigned short Host;
160 unsigned short RupNum;
161};
162
163struct IdentifyRta
164{
165 ulong RtaUnique;
166 uchar ID;
167};
168
169struct KillNeighbour
170{
171 ulong UniqueNum;
172 uchar Link;
173};
174
175struct rioVersion {
176 char version[MAX_VERSION_LEN];
177 char relid[MAX_VERSION_LEN];
178 int buildLevel;
179 char buildDate[MAX_VERSION_LEN];
180};
181
182
183/*
184** RIOC commands are for the daemon type operations
185**
186** 09.12.1998 ARG - ESIL 0776 part fix
187** Definition for 'RIOC' also appears in rioioctl.h, so we'd better do a
188** #ifndef here first.
189** rioioctl.h also now has #define 'RIO_QUICK_CHECK' as this ioctl is now
190** allowed to be used by customers.
191*/
192#ifndef RIOC
193#define RIOC ('R'<<8)|('i'<<16)|('o'<<24)
194#endif
195
196/*
197** Boot stuff
198*/
199#define RIO_GET_TABLE (RIOC | 100)
200#define RIO_PUT_TABLE (RIOC | 101)
201#define RIO_ASSIGN_RTA (RIOC | 102)
202#define RIO_DELETE_RTA (RIOC | 103)
203#define RIO_HOST_FOAD (RIOC | 104)
204#define RIO_QUICK_CHECK (RIOC | 105)
205#define RIO_SIGNALS_ON (RIOC | 106)
206#define RIO_SIGNALS_OFF (RIOC | 107)
207#define RIO_CHANGE_NAME (RIOC | 108)
208#define RIO_DOWNLOAD (RIOC | 109)
209#define RIO_GET_LOG (RIOC | 110)
210#define RIO_SETUP_PORTS (RIOC | 111)
211#define RIO_ALL_MODEM (RIOC | 112)
212
213/*
214** card state, debug stuff
215*/
216#define RIO_NUM_HOSTS (RIOC | 120)
217#define RIO_HOST_LPB (RIOC | 121)
218#define RIO_HOST_RUP (RIOC | 122)
219#define RIO_HOST_PORT (RIOC | 123)
220#define RIO_PARMS (RIOC | 124)
221#define RIO_HOST_REQ (RIOC | 125)
222#define RIO_READ_CONFIG (RIOC | 126)
223#define RIO_SET_CONFIG (RIOC | 127)
224#define RIO_VERSID (RIOC | 128)
225#define RIO_FLAGS (RIOC | 129)
226#define RIO_SETDEBUG (RIOC | 130)
227#define RIO_GETDEBUG (RIOC | 131)
228#define RIO_READ_LEVELS (RIOC | 132)
229#define RIO_SET_FAST_BUS (RIOC | 133)
230#define RIO_SET_SLOW_BUS (RIOC | 134)
231#define RIO_SET_BYTE_MODE (RIOC | 135)
232#define RIO_SET_WORD_MODE (RIOC | 136)
233#define RIO_STREAM_INFO (RIOC | 137)
234#define RIO_START_POLLER (RIOC | 138)
235#define RIO_STOP_POLLER (RIOC | 139)
236#define RIO_LAST_ERROR (RIOC | 140)
237#define RIO_TICK (RIOC | 141)
238#define RIO_TOCK (RIOC | 241) /* I did this on purpose, you know. */
239#define RIO_SEND_PACKET (RIOC | 142)
240#define RIO_SET_BUSY (RIOC | 143)
241#define SPECIAL_RUP_CMD (RIOC | 144)
242#define RIO_FOAD_RTA (RIOC | 145)
243#define RIO_ZOMBIE_RTA (RIOC | 146)
244#define RIO_IDENTIFY_RTA (RIOC | 147)
245#define RIO_KILL_NEIGHBOUR (RIOC | 148)
246#define RIO_DEBUG_MEM (RIOC | 149)
247/*
248** 150 - 167 used..... See below
249*/
250#define RIO_GET_PORT_SETUP (RIOC | 168)
251#define RIO_RESUME (RIOC | 169)
252#define RIO_MESG (RIOC | 170)
253#define RIO_NO_MESG (RIOC | 171)
254#define RIO_WHAT_MESG (RIOC | 172)
255#define RIO_HOST_DPRAM (RIOC | 173)
256#define RIO_MAP_B50_TO_50 (RIOC | 174)
257#define RIO_MAP_B50_TO_57600 (RIOC | 175)
258#define RIO_MAP_B110_TO_110 (RIOC | 176)
259#define RIO_MAP_B110_TO_115200 (RIOC | 177)
260#define RIO_GET_PORT_PARAMS (RIOC | 178)
261#define RIO_SET_PORT_PARAMS (RIOC | 179)
262#define RIO_GET_PORT_TTY (RIOC | 180)
263#define RIO_SET_PORT_TTY (RIOC | 181)
264#define RIO_SYSLOG_ONLY (RIOC | 182)
265#define RIO_SYSLOG_CONS (RIOC | 183)
266#define RIO_CONS_ONLY (RIOC | 184)
267#define RIO_BLOCK_OPENS (RIOC | 185)
268
269/*
270** 02.03.1999 ARG - ESIL 0820 fix :
271** RIOBootMode is no longer use by the driver, so these ioctls
272** are now obsolete :
273**
274#define RIO_GET_BOOT_MODE (RIOC | 186)
275#define RIO_SET_BOOT_MODE (RIOC | 187)
276**
277*/
278
279#define RIO_MEM_DUMP (RIOC | 189)
280#define RIO_READ_REGISTER (RIOC | 190)
281#define RIO_GET_MODTYPE (RIOC | 191)
282#define RIO_SET_TIMER (RIOC | 192)
283#define RIO_READ_CHECK (RIOC | 196)
284#define RIO_WAITING_FOR_RESTART (RIOC | 197)
285#define RIO_BIND_RTA (RIOC | 198)
286#define RIO_GET_BINDINGS (RIOC | 199)
287#define RIO_PUT_BINDINGS (RIOC | 200)
288
289#define RIO_MAKE_DEV (RIOC | 201)
290#define RIO_MINOR (RIOC | 202)
291
292#define RIO_IDENTIFY_DRIVER (RIOC | 203)
293#define RIO_DISPLAY_HOST_CFG (RIOC | 204)
294
295
296/*
297** MAKE_DEV / MINOR stuff
298*/
299#define RIO_DEV_DIRECT 0x0000
300#define RIO_DEV_MODEM 0x0200
301#define RIO_DEV_XPRINT 0x0400
302#define RIO_DEV_MASK 0x0600
303
304/*
305** port management, xprint stuff
306*/
307#define rIOCN(N) (RIOC|(N))
308#define rIOCR(N,T) (RIOC|(N))
309#define rIOCW(N,T) (RIOC|(N))
310
311#define RIO_GET_XP_ON rIOCR(150,char[16]) /* start xprint string */
312#define RIO_SET_XP_ON rIOCW(151,char[16])
313#define RIO_GET_XP_OFF rIOCR(152,char[16]) /* finish xprint string */
314#define RIO_SET_XP_OFF rIOCW(153,char[16])
315#define RIO_GET_XP_CPS rIOCR(154,int) /* xprint CPS */
316#define RIO_SET_XP_CPS rIOCW(155,int)
317#define RIO_GET_IXANY rIOCR(156,int) /* ixany allowed? */
318#define RIO_SET_IXANY rIOCW(157,int)
319#define RIO_SET_IXANY_ON rIOCN(158) /* allow ixany */
320#define RIO_SET_IXANY_OFF rIOCN(159) /* disallow ixany */
321#define RIO_GET_MODEM rIOCR(160,int) /* port is modem/direct line? */
322#define RIO_SET_MODEM rIOCW(161,int)
323#define RIO_SET_MODEM_ON rIOCN(162) /* port is a modem */
324#define RIO_SET_MODEM_OFF rIOCN(163) /* port is direct */
325#define RIO_GET_IXON rIOCR(164,int) /* ixon allowed? */
326#define RIO_SET_IXON rIOCW(165,int)
327#define RIO_SET_IXON_ON rIOCN(166) /* allow ixon */
328#define RIO_SET_IXON_OFF rIOCN(167) /* disallow ixon */
329
330#define RIO_GET_SIVIEW ((('s')<<8) | 106) /* backwards compatible with SI */
331
332#define RIO_IOCTL_UNKNOWN -2
333
334#endif
diff --git a/drivers/char/rio/data.h b/drivers/char/rio/data.h
new file mode 100644
index 000000000000..dabc2d1fa40f
--- /dev/null
+++ b/drivers/char/rio/data.h
@@ -0,0 +1,40 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : data.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:09
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)data.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_datadex__
34#define __rio_datadex__
35
36#ifndef lint
37static char *_data_h_sccs_ = "@(#)data.h 1.2";
38#endif
39
40#endif
diff --git a/drivers/char/rio/debug.h b/drivers/char/rio/debug.h
new file mode 100644
index 000000000000..b6e0d0935552
--- /dev/null
+++ b/drivers/char/rio/debug.h
@@ -0,0 +1,39 @@
1/*
2** File: debug.h
3**
4** Author: David Dix
5**
6** Created: 12th March 1993
7**
8** Last modified: 93/04/27
9**
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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
28#ifndef _debug_h_
29#define _debug_h_
30
31
32#if defined(DCIRRUS)
33#define DBPACKET(pkt, opt, str, chn) debug_packet((pkt), (opt), (str), (chn))
34#else
35#define DBPACKET(pkt, opt, str, c)
36#endif /* DCIRRUS */
37
38
39#endif /* _debug_h_ */
diff --git a/drivers/char/rio/defaults.h b/drivers/char/rio/defaults.h
new file mode 100644
index 000000000000..2e7309e27622
--- /dev/null
+++ b/drivers/char/rio/defaults.h
@@ -0,0 +1,59 @@
1
2/****************************************************************************
3 ******* *******
4 ******* D E F A U L T S
5 ******* *******
6 ****************************************************************************
7
8 Author : Ian Nandhra
9 Date :
10
11 *
12 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 Version : 0.01
29
30
31 Mods
32 ----------------------------------------------------------------------------
33 Date By Description
34 ----------------------------------------------------------------------------
35
36 ***************************************************************************/
37
38#ifndef lint
39#ifdef SCCS
40static char *_rio_defaults_h_sccs = "@(#)defaults.h 1.1" ;
41#endif
42#endif
43
44
45#define MILLISECOND (int) (1000/64) /* 15.625 low ticks */
46#define SECOND (int) 15625 /* Low priority ticks */
47
48#ifdef RTA
49#define RX_LIMIT (ushort) 3
50#endif
51#ifdef HOST
52#define RX_LIMIT (ushort) 1
53#endif
54
55#define LINK_TIMEOUT (int) (POLL_PERIOD / 2)
56
57
58/*********** end of file ***********/
59
diff --git a/drivers/char/rio/eisa.h b/drivers/char/rio/eisa.h
new file mode 100644
index 000000000000..59371b0528b0
--- /dev/null
+++ b/drivers/char/rio/eisa.h
@@ -0,0 +1,104 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6
7 *
8 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23**
24** Module : eisa.h
25** SID : 1.2
26** Last Modified : 11/6/98 11:34:10
27** Retrieved : 11/6/98 11:34:21
28**
29** ident @(#)eisa.h 1.2
30**
31** -----------------------------------------------------------------------------
32*/
33
34#ifndef __rio_eisa_h__
35#define __rio_eisa_h__
36
37#ifdef SCCS_LABELS
38#ifndef lint
39static char *_eisa_h_sccs_ = "@(#)eisa.h 1.2";
40#endif
41#endif
42
43/*
44** things to do with the EISA bus
45*/
46
47#define RIO_EISA_STRING_ADDRESS 0xfffd9 /* where EISA is stored */
48
49#define RIO_MAX_EISA_SLOTS 16 /* how many EISA slots? */
50
51#define RIO_EISA_IDENT 0x984D /* Specialix */
52#define RIO_EISA_PRODUCT_CODE 0x14 /* Code 14 */
53#define RIO_EISA_ENABLE_BIT 0x01 /* To enable card */
54
55#define EISA_MEMORY_BASE_LO 0xC00 /* A16-A23 */
56#define EISA_MEMORY_BASE_HI 0xC01 /* A24-A31 */
57#define EISA_INTERRUPT_VEC 0xC02 /* see below */
58#define EISA_CONTROL_PORT 0xC02 /* see below */
59#define EISA_INTERRUPT_RESET 0xC03 /* read to clear IRQ */
60
61#define EISA_PRODUCT_IDENT_LO 0xC80 /* where RIO_EISA_IDENT is */
62#define EISA_PRODUCT_IDENT_HI 0xC81
63#define EISA_PRODUCT_NUMBER 0xC82 /* where PROD_CODE is */
64#define EISA_REVISION_NUMBER 0xC83 /* revision (1dp) */
65#define EISA_ENABLE 0xC84 /* set LSB to enable card */
66#define EISA_UNIQUE_NUM_0 0xC88 /* vomit */
67#define EISA_UNIQUE_NUM_1 0xC8A
68#define EISA_UNIQUE_NUM_2 0xC90 /* bit strangely arranged */
69#define EISA_UNIQUE_NUM_3 0xC92
70#define EISA_MANUF_YEAR 0xC98 /* when */
71#define EISA_MANUF_WEEK 0xC9A /* more when */
72
73#define EISA_TP_BOOT_FROM_RAM 0x01
74#define EISA_TP_BOOT_FROM_LINK 0x00
75#define EISA_TP_FAST_LINKS 0x02
76#define EISA_TP_SLOW_LINKS 0x00
77#define EISA_TP_BUS_ENABLE 0x04
78#define EISA_TP_BUS_DISABLE 0x00
79#define EISA_TP_RUN 0x08
80#define EISA_TP_RESET 0x00
81#define EISA_POLLED 0x00
82#define EISA_IRQ_3 0x30
83#define EISA_IRQ_4 0x40
84#define EISA_IRQ_5 0x50
85#define EISA_IRQ_6 0x60
86#define EISA_IRQ_7 0x70
87#define EISA_IRQ_9 0x90
88#define EISA_IRQ_10 0xA0
89#define EISA_IRQ_11 0xB0
90#define EISA_IRQ_12 0xC0
91#define EISA_IRQ_14 0xE0
92#define EISA_IRQ_15 0xF0
93
94#define EISA_INTERRUPT_MASK 0xF0
95#define EISA_CONTROL_MASK 0x0F
96
97#define RIO_EISA_DEFAULT_MODE EISA_TP_SLOW_LINKS
98
99#define RIOEisaToIvec(X) (uchar )((uchar)((X) & EISA_INTERRUPT_MASK)>>4)
100
101#define INBZ(z,x) inb(((z)<<12) | (x))
102#define OUTBZ(z,x,y) outb((((z)<<12) | (x)), y)
103
104#endif /* __rio_eisa_h__ */
diff --git a/drivers/char/rio/enable.h b/drivers/char/rio/enable.h
new file mode 100644
index 000000000000..8e9a419e15b0
--- /dev/null
+++ b/drivers/char/rio/enable.h
@@ -0,0 +1,50 @@
1/****************************************************************************
2 ******* *******
3 ******* E N A B L E H E A D E R S
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef lint
38#ifdef SCCS
39static char *_rio_enable_h_sccs = "@(#)enable.h 1.1" ;
40#endif
41#endif
42
43
44#define ENABLE_LTT TRUE
45#define ENABLE_LRT TRUE
46
47
48/*********** end of file ***********/
49
50
diff --git a/drivers/char/rio/error.h b/drivers/char/rio/error.h
new file mode 100644
index 000000000000..229438e355f2
--- /dev/null
+++ b/drivers/char/rio/error.h
@@ -0,0 +1,85 @@
1
2/****************************************************************************
3 ******* *******
4 ******* E R R O R H E A D E R F I L E
5 ******* *******
6 ****************************************************************************
7
8 Author : Ian Nandhra
9 Date :
10
11 *
12 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 Version : 0.01
29
30
31 Mods
32 ----------------------------------------------------------------------------
33 Date By Description
34 ----------------------------------------------------------------------------
35
36 ***************************************************************************/
37
38#ifndef lint
39/* static char *_rio_error_h_sccs = "@(#)error.h 1.3"; */
40#endif
41
42#define E_NO_ERROR ((ushort) 0)
43#define E_PROCESS_NOT_INIT ((ushort) 1)
44#define E_LINK_TIMEOUT ((ushort) 2)
45#define E_NO_ROUTE ((ushort) 3)
46#define E_CONFUSED ((ushort) 4)
47#define E_HOME ((ushort) 5)
48#define E_CSUM_FAIL ((ushort) 6)
49#define E_DISCONNECTED ((ushort) 7)
50#define E_BAD_RUP ((ushort) 8)
51#define E_NO_VIRGIN ((ushort) 9)
52#define E_BOOT_RUP_BUSY ((ushort) 10)
53
54
55
56 /*************************************************
57 * Parsed to mem_halt()
58 ************************************************/
59#define E_CHANALLOC ((ushort) 0x80)
60#define E_POLL_ALLOC ((ushort) 0x81)
61#define E_LTTWAKE ((ushort) 0x82)
62#define E_LTT_ALLOC ((ushort) 0x83)
63#define E_LRT_ALLOC ((ushort) 0x84)
64#define E_CIRRUS ((ushort) 0x85)
65#define E_MONITOR ((ushort) 0x86)
66#define E_PHB_ALLOC ((ushort) 0x87)
67#define E_ARRAY_ALLOC ((ushort) 0x88)
68#define E_QBUF_ALLOC ((ushort) 0x89)
69#define E_PKT_ALLOC ((ushort) 0x8a)
70#define E_GET_TX_Q_BUF ((ushort) 0x8b)
71#define E_GET_RX_Q_BUF ((ushort) 0x8c)
72#define E_MEM_OUT ((ushort) 0x8d)
73#define E_MMU_INIT ((ushort) 0x8e)
74#define E_LTT_INIT ((ushort) 0x8f)
75#define E_LRT_INIT ((ushort) 0x90)
76#define E_LINK_RUN ((ushort) 0x91)
77#define E_MONITOR_ALLOC ((ushort) 0x92)
78#define E_MONITOR_INIT ((ushort) 0x93)
79#define E_POLL_INIT ((ushort) 0x94)
80
81
82/*********** end of file ***********/
83
84
85
diff --git a/drivers/char/rio/errors.h b/drivers/char/rio/errors.h
new file mode 100644
index 000000000000..f920b9f3e2bd
--- /dev/null
+++ b/drivers/char/rio/errors.h
@@ -0,0 +1,104 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : errors.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:10
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)errors.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_errors_h__
34#define __rio_errors_h__
35
36#ifdef SCCS_LABELS
37#ifndef lint
38static char *_errors_h_sccs_ = "@(#)errors.h 1.2";
39#endif
40#endif
41
42/*
43** error codes
44*/
45
46#define NOTHING_WRONG_AT_ALL 0
47#define BAD_CHARACTER_IN_NAME 1
48#define TABLE_ENTRY_ISNT_PROPERLY_NULL 2
49#define UNKNOWN_HOST_NUMBER 3
50#define ZERO_RTA_ID 4
51#define BAD_RTA_ID 5
52#define DUPLICATED_RTA_ID 6
53#define DUPLICATE_UNIQUE_NUMBER 7
54#define BAD_TTY_NUMBER 8
55#define TTY_NUMBER_IN_USE 9
56#define NAME_USED_TWICE 10
57#define HOST_ID_NOT_ZERO 11
58#define BOOT_IN_PROGRESS 12
59#define COPYIN_FAILED 13
60#define HOST_FILE_TOO_LARGE 14
61#define COPYOUT_FAILED 15
62#define NOT_SUPER_USER 16
63#define RIO_ALREADY_POLLING 17
64
65#define ID_NUMBER_OUT_OF_RANGE 18
66#define PORT_NUMBER_OUT_OF_RANGE 19
67#define HOST_NUMBER_OUT_OF_RANGE 20
68#define RUP_NUMBER_OUT_OF_RANGE 21
69#define TTY_NUMBER_OUT_OF_RANGE 22
70#define LINK_NUMBER_OUT_OF_RANGE 23
71
72#define HOST_NOT_RUNNING 24
73#define IOCTL_COMMAND_UNKNOWN 25
74#define RIO_SYSTEM_HALTED 26
75#define WAIT_FOR_DRAIN_BROKEN 27
76#define PORT_NOT_MAPPED_INTO_SYSTEM 28
77#define EXCLUSIVE_USE_SET 29
78#define WAIT_FOR_NOT_CLOSING_BROKEN 30
79#define WAIT_FOR_PORT_TO_OPEN_BROKEN 31
80#define WAIT_FOR_CARRIER_BROKEN 32
81#define WAIT_FOR_NOT_IN_USE_BROKEN 33
82#define WAIT_FOR_CAN_ADD_COMMAND_BROKEN 34
83#define WAIT_FOR_ADD_COMMAND_BROKEN 35
84#define WAIT_FOR_NOT_PARAM_BROKEN 36
85#define WAIT_FOR_RETRY_BROKEN 37
86#define HOST_HAS_ALREADY_BEEN_BOOTED 38
87#define UNIT_IS_IN_USE 39
88#define COULDNT_FIND_ENTRY 40
89#define RTA_UNIQUE_NUMBER_ZERO 41
90#define CLOSE_COMMAND_FAILED 42
91#define WAIT_FOR_CLOSE_BROKEN 43
92#define CPS_VALUE_OUT_OF_RANGE 44
93#define ID_ALREADY_IN_USE 45
94#define SIGNALS_ALREADY_SET 46
95#define NOT_RECEIVING_PROCESS 47
96#define RTA_NUMBER_WRONG 48
97#define NO_SUCH_PRODUCT 49
98#define HOST_SYSPORT_BAD 50
99#define ID_NOT_TENTATIVE 51
100#define XPRINT_CPS_OUT_OF_RANGE 52
101#define NOT_ENOUGH_CORE_FOR_PCI_COPY 53
102
103
104#endif /* __rio_errors_h__ */
diff --git a/drivers/char/rio/formpkt.h b/drivers/char/rio/formpkt.h
new file mode 100644
index 000000000000..a8b65ae0de90
--- /dev/null
+++ b/drivers/char/rio/formpkt.h
@@ -0,0 +1,154 @@
1
2
3/****************************************************************************
4 ******* *******
5 ******* F O R M P A C K E T H E A D E R F I L E
6 ******* *******
7 ****************************************************************************
8
9 Author : Ian Nandhra
10 Date :
11
12 *
13 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
29 Version : 0.01
30
31
32 Mods
33 ----------------------------------------------------------------------------
34 Date By Description
35 ----------------------------------------------------------------------------
36
37 ***************************************************************************/
38
39#ifndef _formpkt_h
40#define _formpkt_h 1
41
42#ifndef lint
43#ifdef SCCS
44static char *_rio_formpkt_h_sccs = "@(#)formpkt.h 1.1" ;
45#endif
46#endif
47
48typedef struct FORM_BOOT_PKT_1 FORM_BOOT_PKT_1 ;
49struct FORM_BOOT_PKT_1 {
50 ushort pkt_number ;
51 ushort pkt_total ;
52 ushort boot_top ;
53 } ;
54
55typedef struct FORM_BOOT_PKT_2 FORM_BOOT_PKT_2 ;
56struct FORM_BOOT_PKT_2 {
57 ushort pkt_number ;
58 char boot_data[10] ;
59 } ;
60
61
62typedef struct FORM_ATTACH_RTA FORM_ATTACH_RTA ;
63struct FORM_ATTACH_RTA {
64 char cmd_code ;
65 char booter_serial[4] ;
66 char booter_link ;
67 char bootee_serial[4] ;
68 char bootee_link ;
69 } ;
70
71
72typedef struct FORM_BOOT_ID FORM_BOOT_ID ;
73struct FORM_BOOT_ID {
74 char cmd_code ;
75 char bootee_serial[4] ;
76 char bootee_prod_id ;
77 char bootee_link ;
78 } ;
79
80
81
82typedef struct FORM_ROUTE_1 FORM_ROUTE_1 ;
83struct FORM_ROUTE_1 {
84 char cmd_code ;
85 char pkt_number ;
86 char total_in_sequence ;
87 char unit_id ;
88 char host_unit_id ;
89 } ;
90
91typedef struct FORM_ROUTE_2 FORM_ROUTE_2 ;
92struct FORM_ROUTE_2 {
93 char cmd_code ;
94 char pkt_number ;
95 char total_in_sequence ;
96 char route_data[9] ;
97 } ;
98
99typedef struct FORM_ROUTE_REQ FORM_ROUTE_REQ ;
100struct FORM_ROUTE_REQ {
101 char cmd_code ;
102 char pkt_number ;
103 char total_in_sequence ;
104 char route_data[10] ;
105 } ;
106
107
108typedef struct FORM_ERROR FORM_ERROR ;
109struct FORM_ERROR {
110 char cmd_code ;
111 char error_code ;
112
113 } ;
114
115typedef struct FORM_STATUS FORM_STATUS ;
116struct FORM_STATUS {
117 char cmd_code ;
118 char status_code ;
119 char last_packet_valid ;
120 char tx_buffer ;
121 char rx_buffer ;
122 char port_status ;
123 char phb_status ;
124 } ;
125
126
127typedef struct FORM_LINK_STATUS FORM_LINK_STATUS ;
128struct FORM_LINK_STATUS {
129 char cmd_code ;
130 char status_code ;
131 char link_number ;
132 ushort rx_errors ;
133 ushort tx_errors ;
134 ushort csum_errors ;
135 ushort disconnects ;
136 } ;
137
138
139
140typedef struct FORM_PARTITION FORM_PARTITION ;
141struct FORM_PARTITION {
142 char cmd_code ;
143 char status_code ;
144 char port_number ;
145 char tx_max ;
146 char rx_max ;
147 char rx_limit ;
148 } ;
149
150
151#endif
152
153/*********** end of file ***********/
154
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
new file mode 100644
index 000000000000..e8f3860f4726
--- /dev/null
+++ b/drivers/char/rio/func.h
@@ -0,0 +1,154 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : func.h
24** SID : 1.3
25** Last Modified : 11/6/98 11:34:10
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)func.h 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __func_h_def
34#define __func_h_def
35
36#include <linux/kdev_t.h>
37
38#ifdef SCCS_LABELS
39#ifndef lint
40static char *_func_h_sccs_ = "@(#)func.h 1.3";
41#endif
42#endif
43
44/* rioboot.c */
45int RIOBootCodeRTA(struct rio_info *, struct DownLoad *);
46int RIOBootCodeHOST(struct rio_info *, register struct DownLoad *);
47int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *);
48void msec_timeout(struct Host *);
49int RIOBootRup(struct rio_info *, uint, struct Host *, struct PKT *);
50int RIOBootOk(struct rio_info *,struct Host *, ulong);
51int RIORtaBound(struct rio_info *, uint);
52void FillSlot(int, int, uint, struct Host *);
53
54/* riocmd.c */
55int RIOFoadRta(struct Host *, struct Map *);
56int RIOZombieRta(struct Host *, struct Map *);
57int RIOCommandRta(struct rio_info *, uint, int (* func)( struct Host *,
58 struct Map *));
59int RIOIdentifyRta(struct rio_info *, caddr_t);
60int RIOKillNeighbour(struct rio_info *, caddr_t);
61int RIOSuspendBootRta(struct Host *, int, int);
62int RIOFoadWakeup(struct rio_info *);
63struct CmdBlk * RIOGetCmdBlk(void);
64void RIOFreeCmdBlk(struct CmdBlk *);
65int RIOQueueCmdBlk(struct Host *, uint, struct CmdBlk *);
66void RIOPollHostCommands(struct rio_info *, struct Host *);
67int RIOWFlushMark(int, struct CmdBlk *);
68int RIORFlushEnable(int, struct CmdBlk *);
69int RIOUnUse(int, struct CmdBlk *);
70void ShowPacket(uint, struct PKT *);
71
72/* rioctrl.c */
73int copyin(int, caddr_t, int);
74int riocontrol(struct rio_info *, dev_t,int,caddr_t,int);
75int RIOPreemptiveCmd(struct rio_info *,struct Port *,uchar);
76
77/* rioinit.c */
78void rioinit(struct rio_info *, struct RioHostInfo *);
79void RIOInitHosts(struct rio_info *, struct RioHostInfo *);
80void RIOISAinit(struct rio_info *,int);
81int RIODoAT(struct rio_info *, int, int);
82caddr_t RIOCheckForATCard(int);
83int RIOAssignAT(struct rio_info *, int, caddr_t, int);
84int RIOBoardTest(paddr_t, caddr_t, uchar, int);
85void RIOAllocDataStructs(struct rio_info *);
86void RIOSetupDataStructs(struct rio_info *);
87int RIODefaultName(struct rio_info *, struct Host *, uint);
88struct rioVersion * RIOVersid(void);
89int RIOMapin(paddr_t, int, caddr_t *);
90void RIOMapout(paddr_t, long, caddr_t);
91void RIOHostReset(uint, volatile struct DpRam *, uint);
92
93/* riointr.c */
94void RIOTxEnable(char *);
95void RIOServiceHost(struct rio_info *, struct Host *, int);
96int riotproc(struct rio_info *, register struct ttystatics *, int, int);
97
98/* rioparam.c */
99int RIOParam(struct Port *, int, int, int);
100int RIODelay(struct Port *PortP, int);
101int RIODelay_ni(struct Port *PortP, int);
102void ms_timeout(struct Port *);
103int can_add_transmit(struct PKT **, struct Port *);
104void add_transmit(struct Port *);
105void put_free_end(struct Host *, struct PKT *);
106int can_remove_receive(struct PKT **, struct Port *);
107void remove_receive(struct Port *);
108
109/* rioroute.c */
110int RIORouteRup(struct rio_info *, uint, struct Host *, struct PKT *);
111void RIOFixPhbs(struct rio_info *, struct Host *, uint);
112uint GetUnitType(uint);
113int RIOSetChange(struct rio_info *);
114int RIOFindFreeID(struct rio_info *, struct Host *, uint *, uint *);
115
116
117/* riotty.c */
118
119int riotopen(struct tty_struct * tty, struct file * filp);
120int riotclose(void *ptr);
121int riotioctl(struct rio_info *, struct tty_struct *, register int, register caddr_t);
122void ttyseth(struct Port *, struct ttystatics *, struct old_sgttyb *sg);
123
124/* riotable.c */
125int RIONewTable(struct rio_info *);
126int RIOApel(struct rio_info *);
127int RIODeleteRta(struct rio_info *, struct Map *);
128int RIOAssignRta(struct rio_info *, struct Map *);
129int RIOReMapPorts(struct rio_info *, struct Host *, struct Map *);
130int RIOChangeName(struct rio_info *, struct Map*);
131
132#if 0
133/* riodrvr.c */
134struct rio_info * rio_install(struct RioHostInfo *);
135int rio_uninstall(register struct rio_info *);
136int rio_open(struct rio_info *, int, struct file *);
137int rio_close(struct rio_info *, struct file *);
138int rio_read(struct rio_info *, struct file *, char *, int);
139int rio_write(struct rio_info *, struct file * f, char *, int);
140int rio_ioctl(struct rio_info *, struct file *, int, char *);
141int rio_select(struct rio_info *, struct file * f, int, struct sel *);
142int rio_intr(char *);
143int rio_isr_thread(char *);
144struct rio_info * rio_info_store( int cmd, struct rio_info * p);
145#endif
146
147extern int rio_pcicopy(char *src, char *dst, int n);
148extern int rio_minor (struct tty_struct *tty);
149extern int rio_ismodem (struct tty_struct *tty);
150extern void rio_udelay (int usecs);
151
152extern void rio_start_card_running (struct Host * HostP);
153
154#endif /* __func_h_def */
diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h
new file mode 100644
index 000000000000..4c65963870a4
--- /dev/null
+++ b/drivers/char/rio/host.h
@@ -0,0 +1,134 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : host.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:10
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)host.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_host_h__
34#define __rio_host_h__
35
36#ifdef SCCS_LABELS
37#ifndef lint
38static char *_host_h_sccs_ = "@(#)host.h 1.2";
39#endif
40#endif
41
42/*
43** the host structure - one per host card in the system.
44*/
45
46#define MAX_EXTRA_UNITS 64
47
48/*
49** Host data structure. This is used for the software equiv. of
50** the host.
51*/
52struct Host
53{
54 uchar Type; /* RIO_EISA, RIO_MCA, ... */
55 uchar Ivec; /* POLLED or ivec number */
56 uchar Mode; /* Control stuff */
57 uchar Slot; /* Slot */
58 volatile caddr_t Caddr; /* KV address of DPRAM */
59 volatile struct DpRam *CardP; /* KV address of DPRAM, with overlay */
60 paddr_t PaddrP; /* Phys. address of DPRAM */
61 char Name[MAX_NAME_LEN]; /* The name of the host */
62 uint UniqueNum; /* host unique number */
63 spinlock_t HostLock; /* Lock structure for MPX */
64 /*struct pci_devinfo PciDevInfo; *//* PCI Bus/Device/Function stuff */
65 /*struct lockb HostLock; *//* Lock structure for MPX */
66 uint WorkToBeDone; /* set to true each interrupt */
67 uint InIntr; /* Being serviced? */
68 uint IntSrvDone;/* host's interrupt has been serviced */
69 int (*Copy)( caddr_t, caddr_t, int ); /* copy func */
70 struct timer_list timer;
71 /*
72 ** I M P O R T A N T !
73 **
74 ** The rest of this data structure is cleared to zero after
75 ** a RIO_HOST_FOAD command.
76 */
77
78 ulong Flags; /* Whats going down */
79#define RC_WAITING 0
80#define RC_STARTUP 1
81#define RC_RUNNING 2
82#define RC_STUFFED 3
83#define RC_SOMETHING 4
84#define RC_SOMETHING_NEW 5
85#define RC_SOMETHING_ELSE 6
86#define RC_READY 7
87#define RUN_STATE 7
88/*
89** Boot mode applies to the way in which hosts in this system will
90** boot RTAs
91*/
92#define RC_BOOT_ALL 0x8 /* Boot all RTAs attached */
93#define RC_BOOT_OWN 0x10 /* Only boot RTAs bound to this system */
94#define RC_BOOT_NONE 0x20 /* Don't boot any RTAs (slave mode) */
95
96 struct Top Topology[LINKS_PER_UNIT]; /* one per link */
97 struct Map Mapping[MAX_RUP]; /* Mappings for host */
98 struct PHB *PhbP; /* Pointer to the PHB array */
99 ushort *PhbNumP; /* Ptr to Number of PHB's */
100 struct LPB *LinkStrP ; /* Link Structure Array */
101 struct RUP *RupP; /* Sixteen real rups here */
102 struct PARM_MAP *ParmMapP; /* points to the parmmap */
103 uint ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */
104 uint NumExtraBooted; /* how many of the above */
105 /*
106 ** Twenty logical rups.
107 ** The first sixteen are the real Rup entries (above), the last four
108 ** are the link RUPs.
109 */
110 struct UnixRup UnixRups[MAX_RUP+LINKS_PER_UNIT];
111 int timeout_id; /* For calling 100 ms delays */
112 int timeout_sem;/* For calling 100 ms delays */
113 long locks; /* long req'd for set_bit --RR */
114 char ____end_marker____;
115};
116#define Control CardP->DpControl
117#define SetInt CardP->DpSetInt
118#define ResetTpu CardP->DpResetTpu
119#define ResetInt CardP->DpResetInt
120#define Signature CardP->DpSignature
121#define Sram1 CardP->DpSram1
122#define Sram2 CardP->DpSram2
123#define Sram3 CardP->DpSram3
124#define Scratch CardP->DpScratch
125#define __ParmMapR CardP->DpParmMapR
126#define SLX CardP->DpSlx
127#define Revision CardP->DpRevision
128#define Unique CardP->DpUnique
129#define Year CardP->DpYear
130#define Week CardP->DpWeek
131
132#define RIO_DUMBPARM 0x0860 /* what not to expect */
133
134#endif
diff --git a/drivers/char/rio/hosthw.h b/drivers/char/rio/hosthw.h
new file mode 100644
index 000000000000..f6f31ece6e32
--- /dev/null
+++ b/drivers/char/rio/hosthw.h
@@ -0,0 +1,57 @@
1/****************************************************************************
2 ******* *******
3 ******* H O S T H A R D W A R E
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37
38#ifndef lint
39#ifdef SCCS_LABELS
40static char *_rio_hosthw_h_sccs = "@(#)hosthw.h 1.2" ;
41#endif
42#endif
43
44#define SET_OTHER_INTERRUPT ( (volatile u_short *) 0x7c80 )
45#define SET_EISA_INTERRUPT ( (volatile u_short *) 0x7ef0 )
46
47#define EISA_HOST 0x30
48#define AT_HOST 0xa0
49#define MCA_HOST 0xb0
50#define PCI_HOST 0xd0
51
52#define PRODUCT_MASK 0xf0
53
54
55/*********** end of file ***********/
56
57
diff --git a/drivers/char/rio/link.h b/drivers/char/rio/link.h
new file mode 100644
index 000000000000..972250348f4a
--- /dev/null
+++ b/drivers/char/rio/link.h
@@ -0,0 +1,188 @@
1/****************************************************************************
2 ******* *******
3 ******* L I N K
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _link_h
38#define _link_h 1
39
40#ifndef lint
41#ifdef SCCS_LABELS
42/* static char *_rio_link_h_sccs = "@(#)link.h 1.15"; */
43#endif
44#endif
45
46
47
48/*************************************************
49 * Define the Link Status stuff
50 ************************************************/
51#define LRT_ACTIVE ((ushort) 0x01)
52#define LRT_SPARE1 ((ushort) 0x02)
53#define INTRO_RCVD ((ushort) 0x04)
54#define FORCED_DISCONNECT ((ushort) 0x08)
55#define LRT_SPARE2 ((ushort) 0x80)
56
57#define TOP_OF_RTA_RAM ((ushort) 0x7000)
58#define HOST_SERIAL_POINTER (unsigned char **) (TOP_OF_RTA_RAM - 2 * sizeof (ushort))
59
60/* Flags for ltt_status */
61#define WAITING_ACK (ushort) 0x0001
62#define DATA_SENT (ushort) 0x0002
63#define WAITING_RUP (ushort) 0x0004
64#define WAITING_RETRY (ushort) 0x0008
65#define WAITING_TOPOLOGY (ushort) 0x0010
66#define SEND_SYNC (ushort) 0x0020
67#define FOAD_THIS_LINK (ushort) 0x0040
68#define REQUEST_SYNC (ushort) 0x0080
69#define REMOTE_DYING (ushort) 0x0100
70#define DIE_NOW (ushort) 0x0200
71
72/* Boot request stuff */
73#define BOOT_REQUEST ((ushort) 0) /* Request for a boot */
74#define BOOT_ABORT ((ushort) 1) /* Abort a boot */
75#define BOOT_SEQUENCE ((ushort) 2) /* Packet with the number of packets
76 and load address */
77#define BOOT_COMPLETED ((ushort) 3) /* Boot completed */
78
79/* States that a link can be in */
80#define LINK_DISCONNECTED ((ushort) 0) /* Disconnected */
81#define LINK_BOOT1 ((ushort) 1) /* Trying to send 1st stage boot */
82#define LINK_BOOT2 ((ushort) 2) /* Trying to send 2nd stage boot */
83#define LINK_BOOT2WAIT ((ushort) 3) /* Waiting for selftest results */
84#define LINK_BOOT3 ((ushort) 4) /* Trying to send 3rd stage boots */
85#define LINK_SYNC ((ushort) 5) /* Syncing */
86
87#define LINK_INTRO ((ushort) 10) /* Introductory packet */
88#define LINK_SUPPLYID ((ushort) 11) /* Trying to supply an ID */
89#define LINK_TOPOLOGY ((ushort) 12) /* Send a topology update */
90#define LINK_REQUESTID ((ushort) 13) /* Waiting for an ID */
91#define LINK_CONNECTED ((ushort) 14) /* Connected */
92
93#define LINK_INTERCONNECT ((ushort) 20) /* Subnets interconnected */
94
95#define LINK_SPARE ((ushort) 40)
96
97/*
98** Set the default timeout for link communications.
99*/
100#define LINKTIMEOUT (400 * MILLISECOND)
101
102/*
103** LED stuff
104*/
105#if defined(RTA)
106#define LED_OFF ((ushort) 0) /* LED off */
107#define LED_RED ((ushort) 1) /* LED Red */
108#define LED_GREEN ((ushort) 2) /* LED Green */
109#define LED_ORANGE ((ushort) 4) /* LED Orange */
110#define LED_1TO8_OPEN ((ushort) 1) /* Port 1->8 LED on */
111#define LED_9TO16_OPEN ((ushort) 2) /* Port 9->16 LED on */
112#define LED_SET_COLOUR(colour) (link->led = (colour))
113#define LED_OR_COLOUR(colour) (link->led |= (colour))
114#define LED_TIMEOUT(time) (link->led_timeout = RioTimePlus(RioTime(),(time)))
115#else
116#define LED_SET_COLOUR(colour)
117#define LED_OR_COLOUR(colour)
118#define LED_TIMEOUT(time)
119#endif /* RTA */
120
121struct LPB {
122 WORD link_number ; /* Link Number */
123 Channel_ptr in_ch ; /* Link In Channel */
124 Channel_ptr out_ch ; /* Link Out Channel */
125#ifdef RTA
126 uchar stat_led ; /* Port open leds */
127 uchar led ; /* True, light led! */
128#endif
129 BYTE attached_serial[4]; /* Attached serial number */
130 BYTE attached_host_serial[4];
131 /* Serial number of Host who
132 booted the other end */
133 WORD descheduled ; /* Currently Descheduled */
134 WORD state; /* Current state */
135 WORD send_poll ; /* Send a Poll Packet */
136 Process_ptr ltt_p ; /* Process Descriptor */
137 Process_ptr lrt_p ; /* Process Descriptor */
138 WORD lrt_status ; /* Current lrt status */
139 WORD ltt_status ; /* Current ltt status */
140 WORD timeout ; /* Timeout value */
141 WORD topology; /* Topology bits */
142 WORD mon_ltt ;
143 WORD mon_lrt ;
144 WORD WaitNoBoot ; /* Secs to hold off booting */
145 PKT_ptr add_packet_list; /* Add packets to here */
146 PKT_ptr remove_packet_list; /* Send packets from here */
147#ifdef RTA
148#ifdef DCIRRUS
149#define QBUFS_PER_REDIRECT (4 / PKTS_PER_BUFFER + 1)
150#else
151#define QBUFS_PER_REDIRECT (8 / PKTS_PER_BUFFER + 1)
152#endif
153 PKT_ptr_ptr rd_add ; /* Add a new Packet here */
154 Q_BUF_ptr rd_add_qb; /* Pointer to the add Q buf */
155 PKT_ptr_ptr rd_add_st_qbb ; /* Pointer to start of the Q's buf */
156 PKT_ptr_ptr rd_add_end_qbb ; /* Pointer to the end of the Q's buf */
157 PKT_ptr_ptr rd_remove ; /* Remove a Packet here */
158 Q_BUF_ptr rd_remove_qb ; /* Pointer to the remove Q buf */
159 PKT_ptr_ptr rd_remove_st_qbb ; /* Pointer to the start of the Q buf */
160 PKT_ptr_ptr rd_remove_end_qbb ; /* Pointer to the end of the Q buf */
161 ushort pkts_in_q ; /* Packets in queue */
162#endif
163
164 Channel_ptr lrt_fail_chan ; /* Lrt's failure channel */
165 Channel_ptr ltt_fail_chan ; /* Ltt's failure channel */
166
167#if defined (HOST) || defined (INKERNEL)
168 /* RUP structure for HOST to driver communications */
169 struct RUP rup ;
170#endif
171 struct RUP link_rup; /* RUP for the link (POLL,
172 topology etc.) */
173 WORD attached_link ; /* Number of attached link */
174 WORD csum_errors ; /* csum errors */
175 WORD num_disconnects ; /* number of disconnects */
176 WORD num_sync_rcvd ; /* # sync's received */
177 WORD num_sync_rqst ; /* # sync requests */
178 WORD num_tx ; /* Num pkts sent */
179 WORD num_rx ; /* Num pkts received */
180 WORD module_attached; /* Module tpyes of attached */
181 WORD led_timeout; /* LED timeout */
182 WORD first_port; /* First port to service */
183 WORD last_port; /* Last port to service */
184 } ;
185
186#endif
187
188/*********** end of file ***********/
diff --git a/drivers/char/rio/linux_compat.h b/drivers/char/rio/linux_compat.h
new file mode 100644
index 000000000000..d53843abe02d
--- /dev/null
+++ b/drivers/char/rio/linux_compat.h
@@ -0,0 +1,122 @@
1/*
2 * (C) 2000 R.E.Wolff@BitWizard.nl
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <linux/interrupt.h>
20
21
22#define disable(oldspl) save_flags (oldspl)
23#define restore(oldspl) restore_flags (oldspl)
24
25#define sysbrk(x) kmalloc ((x),in_interrupt()? GFP_ATOMIC : GFP_KERNEL)
26#define sysfree(p,size) kfree ((p))
27
28#define WBYTE(p,v) writeb(v, &p)
29#define RBYTE(p) readb (&p)
30#define WWORD(p,v) writew(v, &p)
31#define RWORD(p) readw(&p)
32#define WINDW(p,v) writew(v, p)
33#define RINDW(p) readw(p)
34
35#define DEBUG_ALL
36
37#define cprintf printk
38
39#ifdef __KERNEL__
40#define INKERNEL
41#endif
42
43struct ttystatics {
44 struct termios tm;
45};
46
47#define bzero(d, n) memset((d), 0, (n))
48#define bcopy(src, dest, n) memcpy ((dest), (src), (n))
49
50#define SEM_SIGIGNORE 0x1234
51
52#ifdef DEBUG_SEM
53#define swait(a,b) printk ("waiting: " __FILE__ " line %d\n", __LINE__)
54#define ssignal(sem) printk ("signalling: " __FILE__ " line %d\n", __LINE__)
55
56#define sreset(sem) printk ("sreset: " __FILE__ "\n")
57#define sem_init(sem,v) printk ("sreset: " __FILE__ "\n")
58#endif
59
60
61#define getpid() (current->pid)
62
63#define QSIZE SERIAL_XMIT_SIZE
64
65#define pseterr(errno) return (- errno)
66
67#define V_CBAUD CBAUD
68
69/* For one reason or another rioboot.c uses delay instead of RIODelay. */
70#define delay(x,y) RIODelay(NULL, y)
71
72extern int rio_debug;
73
74#define RIO_DEBUG_INIT 0x000001
75#define RIO_DEBUG_BOOT 0x000002
76#define RIO_DEBUG_CMD 0x000004
77#define RIO_DEBUG_CTRL 0x000008
78#define RIO_DEBUG_INTR 0x000010
79#define RIO_DEBUG_PARAM 0x000020
80#define RIO_DEBUG_ROUTE 0x000040
81#define RIO_DEBUG_TABLE 0x000080
82#define RIO_DEBUG_TTY 0x000100
83#define RIO_DEBUG_FLOW 0x000200
84#define RIO_DEBUG_MODEMSIGNALS 0x000400
85#define RIO_DEBUG_PROBE 0x000800
86#define RIO_DEBUG_CLEANUP 0x001000
87#define RIO_DEBUG_IFLOW 0x002000
88#define RIO_DEBUG_PFE 0x004000
89#define RIO_DEBUG_REC 0x008000
90#define RIO_DEBUG_SPINLOCK 0x010000
91#define RIO_DEBUG_DELAY 0x020000
92#define RIO_DEBUG_MOD_COUNT 0x040000
93
94/* Copied over from riowinif.h . This is ugly. The winif file declares
95also much other stuff which is incompatible with the headers from
96the older driver. The older driver includes "brates.h" which shadows
97the definitions from Linux, and is incompatible... */
98
99/* RxBaud and TxBaud definitions... */
100#define RIO_B0 0x00 /* RTS / DTR signals dropped */
101#define RIO_B50 0x01 /* 50 baud */
102#define RIO_B75 0x02 /* 75 baud */
103#define RIO_B110 0x03 /* 110 baud */
104#define RIO_B134 0x04 /* 134.5 baud */
105#define RIO_B150 0x05 /* 150 baud */
106#define RIO_B200 0x06 /* 200 baud */
107#define RIO_B300 0x07 /* 300 baud */
108#define RIO_B600 0x08 /* 600 baud */
109#define RIO_B1200 0x09 /* 1200 baud */
110#define RIO_B1800 0x0A /* 1800 baud */
111#define RIO_B2400 0x0B /* 2400 baud */
112#define RIO_B4800 0x0C /* 4800 baud */
113#define RIO_B9600 0x0D /* 9600 baud */
114#define RIO_B19200 0x0E /* 19200 baud */
115#define RIO_B38400 0x0F /* 38400 baud */
116#define RIO_B56000 0x10 /* 56000 baud */
117#define RIO_B57600 0x11 /* 57600 baud */
118#define RIO_B64000 0x12 /* 64000 baud */
119#define RIO_B115200 0x13 /* 115200 baud */
120#define RIO_B2000 0x14 /* 2000 baud */
121
122
diff --git a/drivers/char/rio/list.h b/drivers/char/rio/list.h
new file mode 100644
index 000000000000..a4f7f1f56255
--- /dev/null
+++ b/drivers/char/rio/list.h
@@ -0,0 +1,196 @@
1/****************************************************************************
2 ******* *******
3 ******* L I S T *******
4 ******* *******
5 ****************************************************************************
6
7 Author : Jeremy Rolls.
8 Date : 04-Nov-1990
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34 ***************************************************************************/
35
36#ifndef _list_h
37#define _list_h 1
38
39#ifdef SCCS_LABELS
40#ifndef lint
41static char *_rio_list_h_sccs = "@(#)list.h 1.9" ;
42#endif
43#endif
44
45#define PKT_IN_USE 0x1
46
47#ifdef INKERNEL
48
49#define ZERO_PTR (ushort) 0x8000
50#define CaD PortP->Caddr
51
52/*
53** We can add another packet to a transmit queue if the packet pointer pointed
54** to by the TxAdd pointer has PKT_IN_USE clear in its address.
55*/
56
57#ifndef linux
58#if defined( MIPS ) && !defined( MIPSEISA )
59/* May the shoes of the Devil dance on your grave for creating this */
60#define can_add_transmit(PacketP,PortP) \
61 (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,RINDW(PortP->TxAdd))) \
62 & (PKT_IN_USE<<2)))
63
64#elif defined(MIPSEISA) || defined(nx6000) || \
65 defined(drs6000) || defined(UWsparc)
66
67#define can_add_transmit(PacketP,PortP) \
68 (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,RINDW(PortP->TxAdd))) \
69 & PKT_IN_USE))
70
71#else
72#define can_add_transmit(PacketP,PortP) \
73 (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,*PortP->TxAdd)) \
74 & PKT_IN_USE))
75#endif
76
77/*
78** To add a packet to the queue, you set the PKT_IN_USE bit in the address,
79** and then move the TxAdd pointer along one position to point to the next
80** packet pointer. You must wrap the pointer from the end back to the start.
81*/
82#if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc)
83# define add_transmit(PortP) \
84 WINDW(PortP->TxAdd,RINDW(PortP->TxAdd) | PKT_IN_USE);\
85 if (PortP->TxAdd == PortP->TxEnd)\
86 PortP->TxAdd = PortP->TxStart;\
87 else\
88 PortP->TxAdd++;\
89 WWORD(PortP->PhbP->tx_add , RIO_OFF(CaD,PortP->TxAdd));
90#elif defined(AIX)
91# define add_transmit(PortP) \
92 {\
93 register ushort *TxAddP = (ushort *)RIO_PTR(Cad,PortP->TxAddO);\
94 WINDW( TxAddP, RINDW( TxAddP ) | PKT_IN_USE );\
95 if (PortP->TxAddO == PortP->TxEndO )\
96 PortP->TxAddO = PortP->TxStartO;\
97 else\
98 PortP->TxAddO += sizeof(ushort);\
99 WWORD(((PHB *)RIO_PTR(Cad,PortP->PhbO))->tx_add , PortP->TxAddO );\
100 }
101#else
102# define add_transmit(PortP) \
103 *PortP->TxAdd |= PKT_IN_USE;\
104 if (PortP->TxAdd == PortP->TxEnd)\
105 PortP->TxAdd = PortP->TxStart;\
106 else\
107 PortP->TxAdd++;\
108 PortP->PhbP->tx_add = RIO_OFF(CaD,PortP->TxAdd);
109#endif
110
111/*
112** can_remove_receive( PacketP, PortP ) returns non-zero if PKT_IN_USE is set
113** for the next packet on the queue. It will also set PacketP to point to the
114** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
115** then can_remove_receive() returns 0.
116*/
117#if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc)
118# define can_remove_receive(PacketP,PortP) \
119 ((RINDW(PortP->RxRemove) & PKT_IN_USE) ? \
120 (PacketP=(struct PKT *)RIO_PTR(CaD,(RINDW(PortP->RxRemove) & ~PKT_IN_USE))):0)
121#elif defined(AIX)
122# define can_remove_receive(PacketP,PortP) \
123 ((RINDW((ushort *)RIO_PTR(Cad,PortP->RxRemoveO)) & PKT_IN_USE) ? \
124 (PacketP=(struct PKT *)RIO_PTR(Cad,RINDW((ushort *)RIO_PTR(Cad,PortP->RxRemoveO)) & ~PKT_IN_USE)):0)
125#else
126# define can_remove_receive(PacketP,PortP) \
127 ((*PortP->RxRemove & PKT_IN_USE) ? \
128 (PacketP=(struct PKT *)RIO_PTR(CaD,(*PortP->RxRemove & ~PKT_IN_USE))):0)
129#endif
130
131
132/*
133** Will God see it within his heart to forgive us for this thing that
134** we have created? To remove a packet from the receive queue you clear
135** its PKT_IN_USE bit, and then bump the pointers. Once the pointers
136** get to the end, they must be wrapped back to the start.
137*/
138#if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc)
139# define remove_receive(PortP) \
140 WINDW(PortP->RxRemove, (RINDW(PortP->RxRemove) & ~PKT_IN_USE));\
141 if (PortP->RxRemove == PortP->RxEnd)\
142 PortP->RxRemove = PortP->RxStart;\
143 else\
144 PortP->RxRemove++;\
145 WWORD(PortP->PhbP->rx_remove , RIO_OFF(CaD,PortP->RxRemove));
146#elif defined(AIX)
147# define remove_receive(PortP) \
148 {\
149 register ushort *RxRemoveP = (ushort *)RIO_PTR(Cad,PortP->RxRemoveO);\
150 WINDW( RxRemoveP, RINDW( RxRemoveP ) & ~PKT_IN_USE );\
151 if (PortP->RxRemoveO == PortP->RxEndO)\
152 PortP->RxRemoveO = PortP->RxStartO;\
153 else\
154 PortP->RxRemoveO += sizeof(ushort);\
155 WWORD(((PHB *)RIO_PTR(Cad,PortP->PhbO))->rx_remove, PortP->RxRemoveO );\
156 }
157#else
158# define remove_receive(PortP) \
159 *PortP->RxRemove &= ~PKT_IN_USE;\
160 if (PortP->RxRemove == PortP->RxEnd)\
161 PortP->RxRemove = PortP->RxStart;\
162 else\
163 PortP->RxRemove++;\
164 PortP->PhbP->rx_remove = RIO_OFF(CaD,PortP->RxRemove);
165#endif
166#endif
167
168
169#else /* !IN_KERNEL */
170
171#define ZERO_PTR NULL
172
173
174#ifdef HOST
175/* #define can_remove_transmit(pkt,phb) ((((char*)pkt = (*(char**)(phb->tx_remove))-1) || 1)) && (*phb->u3.s2.tx_remove_ptr & PKT_IN_USE)) */
176#define remove_transmit(phb) *phb->u3.s2.tx_remove_ptr &= ~(ushort)PKT_IN_USE;\
177 if (phb->tx_remove == phb->tx_end)\
178 phb->tx_remove = phb->tx_start;\
179 else\
180 phb->tx_remove++;
181#define can_add_receive(phb) !(*phb->u4.s2.rx_add_ptr & PKT_IN_USE)
182#define add_receive(pkt,phb) *phb->rx_add = pkt;\
183 *phb->u4.s2.rx_add_ptr |= PKT_IN_USE;\
184 if (phb->rx_add == phb->rx_end)\
185 phb->rx_add = phb->rx_start;\
186 else\
187 phb->rx_add++;
188#endif
189#endif
190
191#ifdef RTA
192#define splx(oldspl) if ((oldspl) == 0) spl0()
193#endif
194
195#endif /* ifndef _list.h */
196/*********** end of file ***********/
diff --git a/drivers/char/rio/lrt.h b/drivers/char/rio/lrt.h
new file mode 100644
index 000000000000..bbac8fa18fee
--- /dev/null
+++ b/drivers/char/rio/lrt.h
@@ -0,0 +1,55 @@
1/****************************************************************************
2 ******* *******
3 ******* L R T
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef lint
38#ifdef SCCS_LABELS
39static char *_rio_lrt_h_sccs = "@(#)lrt.h 1.1" ;
40#endif
41#endif
42
43
44#ifdef DCIRRUS
45#define LRT_STACK (unsigned short) 600
46#else
47#define LRT_STACK (ushort) 200
48#endif
49
50
51
52/*********** end of file ***********/
53
54
55
diff --git a/drivers/char/rio/ltt.h b/drivers/char/rio/ltt.h
new file mode 100644
index 000000000000..f27dcecf03ca
--- /dev/null
+++ b/drivers/char/rio/ltt.h
@@ -0,0 +1,55 @@
1/****************************************************************************
2 ******* *******
3 ******* L T T
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef lint
38#ifdef SCCS_LABELS
39static char *_rio_ltt_h_sccs = "@(#)ltt.h 1.1" ;
40#endif
41#endif
42
43#ifdef DCIRRUS
44#define LTT_STACK (unsigned short) 600
45#else
46#define LTT_STACK (ushort) 200
47#endif
48
49
50
51
52/*********** end of file ***********/
53
54
55
diff --git a/drivers/char/rio/lttwake.h b/drivers/char/rio/lttwake.h
new file mode 100644
index 000000000000..fe17d0ee4933
--- /dev/null
+++ b/drivers/char/rio/lttwake.h
@@ -0,0 +1,53 @@
1
2
3
4/****************************************************************************
5 ******* *******
6 ******* L T T W A K E U P H E A D E R
7 ******* *******
8 ****************************************************************************
9
10 Author : Ian Nandhra
11 Date :
12
13 *
14 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29
30 Version : 0.01
31
32
33 Mods
34 ----------------------------------------------------------------------------
35 Date By Description
36 ----------------------------------------------------------------------------
37
38 ***************************************************************************/
39
40#ifndef lint
41#ifdef SCCS_LABELS
42static char *_rio_lttwake_h_sccs = "@(#)lttwake.h 1.1" ;
43#endif
44#endif
45
46#define LTT_WAKEUP_STACK 500
47#define LTT_WAKEUP_INTERVAL (int) (500 * MILLISECOND)
48
49
50/*********** end of file ***********/
51
52
53
diff --git a/drivers/char/rio/map.h b/drivers/char/rio/map.h
new file mode 100644
index 000000000000..400645a1ff28
--- /dev/null
+++ b/drivers/char/rio/map.h
@@ -0,0 +1,103 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : map.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:11
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)map.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_map_h__
34#define __rio_map_h__
35
36#ifdef SCCS_LABELS
37static char *_map_h_sccs_ = "@(#)map.h 1.2";
38#endif
39
40/*
41** mapping structure passed to and from the config.rio program to
42** determine the current topology of the world
43*/
44
45#define MAX_MAP_ENTRY 17
46#define TOTAL_MAP_ENTRIES (MAX_MAP_ENTRY*RIO_SLOTS)
47#define MAX_NAME_LEN 32
48
49struct Map
50{
51 uint HostUniqueNum; /* Supporting hosts unique number */
52 uint RtaUniqueNum; /* Unique number */
53 /*
54 ** The next two IDs must be swapped on big-endian architectures
55 ** when using a v2.04 /etc/rio/config with a v3.00 driver (when
56 ** upgrading for example).
57 */
58 ushort ID; /* ID used in the subnet */
59 ushort ID2; /* ID of 2nd block of 8 for 16 port */
60 ulong Flags; /* Booted, ID Given, Disconnected */
61 ulong SysPort; /* First tty mapped to this port */
62 struct Top Topology[LINKS_PER_UNIT]; /* ID connected to each link */
63 char Name[MAX_NAME_LEN]; /* Cute name by which RTA is known */
64};
65
66/*
67** Flag values:
68*/
69#define RTA_BOOTED 0x00000001
70#define RTA_NEWBOOT 0x00000010
71#define MSG_DONE 0x00000020
72#define RTA_INTERCONNECT 0x00000040
73#define RTA16_SECOND_SLOT 0x00000080
74#define BEEN_HERE 0x00000100
75#define SLOT_TENTATIVE 0x40000000
76#define SLOT_IN_USE 0x80000000
77
78/*
79** HostUniqueNum is the unique number from the host card that this RTA
80** is to be connected to.
81** RtaUniqueNum is the unique number of the RTA concerned. It will be ZERO
82** if the slot in the table is unused. If it is the same as the HostUniqueNum
83** then this slot represents a host card.
84** Flags contains current boot/route state info
85** SysPort is a value in the range 0-504, being the number of the first tty
86** on this RTA. Each RTA supports 8 ports. The SysPort value must be modulo 8.
87** SysPort 0-127 correspond to /dev/ttyr001 to /dev/ttyr128, with minor
88** numbers 0-127. SysPort 128-255 correspond to /dev/ttyr129 to /dev/ttyr256,
89** again with minor numbers 0-127, and so on for SysPorts 256-383 and 384-511
90** ID will be in the range 0-16 for a `known' RTA. ID will be 0xFFFF for an
91** unused slot/unknown ID etc.
92** The Topology array contains the ID of the unit connected to each of the
93** four links on this unit. The entry will be 0xFFFF if NOTHING is connected
94** to the link, or will be 0xFF00 if an UNKNOWN unit is connected to the link.
95** The Name field is a null-terminated string, upto 31 characters, containing
96** the 'cute' name that the sysadmin/users know the RTA by. It is permissible
97** for this string to contain any character in the range \040 to \176 inclusive.
98** In particular, ctrl sequences and DEL (0x7F, \177) are not allowed. The
99** special character '%' IS allowable, and needs no special action.
100**
101*/
102
103#endif
diff --git a/drivers/char/rio/mca.h b/drivers/char/rio/mca.h
new file mode 100644
index 000000000000..08a327e473af
--- /dev/null
+++ b/drivers/char/rio/mca.h
@@ -0,0 +1,73 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : mca.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:11
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)mca.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_mca_h__
34#define __rio_mca_h__
35
36#ifdef SCCS_LABELS
37static char *_mca_h_sccs_ = "@(#)mca.h 1.2";
38#endif
39
40/*
41** Micro Channel stuff
42*/
43
44#define McaMaxSlots 8
45#define McaSlotSelect 0x96
46#define McaSlotEnable 0x08
47#define McaIdLow 0x100
48#define McaIdHigh 0x101
49#define McaIrqEnable 0x102
50#define McaMemory 0x103
51#define McaRIOId 0x6a5c
52#define McaIrq9 0x00
53#define McaIrq3 0x02
54#define McaIrq4 0x04
55#define McaIrq7 0x06
56#define McaIrq10 0x08
57#define McaIrq11 0x0A
58#define McaIrq12 0x0C
59#define McaIrq15 0x0E
60#define McaIrqMask 0x0E
61#define McaCardEnable 0x01
62#define McaAddress(X) (((X)&0xFF)<<16)
63
64#define McaTpFastLinks 0x40
65#define McaTpSlowLinks 0x00
66#define McaTpBootFromRam 0x01
67#define McaTpBootFromLink 0x00
68#define McaTpBusEnable 0x02
69#define McaTpBusDisable 0x00
70
71#define RIO_MCA_DEFAULT_MODE SLOW_LINKS
72
73#endif /* __rio_mca_h__ */
diff --git a/drivers/char/rio/mesg.h b/drivers/char/rio/mesg.h
new file mode 100644
index 000000000000..9cf6c0bacea4
--- /dev/null
+++ b/drivers/char/rio/mesg.h
@@ -0,0 +1,41 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : mesg.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:12
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)mesg.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_mesg_h__
34#define __rio_mesg_h__
35
36#ifdef SCCS_LABELS
37static char *_mesg_h_sccs_ = "@(#)mesg.h 1.2";
38#endif
39
40
41#endif /* __rio_mesg_h__ */
diff --git a/drivers/char/rio/param.h b/drivers/char/rio/param.h
new file mode 100644
index 000000000000..2dc30b9aab37
--- /dev/null
+++ b/drivers/char/rio/param.h
@@ -0,0 +1,61 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : param.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:12
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)param.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_param_h__
34#define __rio_param_h__
35
36#ifdef SCCS_LABELS
37static char *_param_h_sccs_ = "@(#)param.h 1.2";
38#endif
39
40
41/*
42** the param command block, as used in OPEN and PARAM calls.
43*/
44
45struct phb_param
46{
47 BYTE Cmd; /* It is very important that these line up */
48 BYTE Cor1; /* with what is expected at the other end. */
49 BYTE Cor2; /* to confirm that you've got it right, */
50 BYTE Cor4; /* check with cirrus/cirrus.h */
51 BYTE Cor5;
52 BYTE TxXon; /* Transmit X-On character */
53 BYTE TxXoff; /* Transmit X-Off character */
54 BYTE RxXon; /* Receive X-On character */
55 BYTE RxXoff; /* Receive X-Off character */
56 BYTE LNext; /* Literal-next character */
57 BYTE TxBaud; /* Transmit baudrate */
58 BYTE RxBaud; /* Receive baudrate */
59};
60
61#endif
diff --git a/drivers/char/rio/parmmap.h b/drivers/char/rio/parmmap.h
new file mode 100644
index 000000000000..46f99dfdac8d
--- /dev/null
+++ b/drivers/char/rio/parmmap.h
@@ -0,0 +1,96 @@
1/****************************************************************************
2 ******* *******
3 ******* H O S T M E M O R Y M A P
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
346/4/1991 jonb Made changes to accommodate Mips R3230 bus
35 ***************************************************************************/
36
37#ifndef _parmap_h
38#define _parmap_h
39
40
41#ifdef SCCS_LABELS
42#ifndef lint
43/* static char *_rio_parmmap_h_sccs = "@(#)parmmap.h 1.4"; */
44#endif
45#endif
46
47typedef struct PARM_MAP PARM_MAP ;
48
49struct PARM_MAP
50{
51PHB_ptr phb_ptr ; /* Pointer to the PHB array */
52WORD_ptr phb_num_ptr ; /* Ptr to Number of PHB's */
53FREE_LIST_ptr free_list; /* Free List pointer */
54FREE_LIST_ptr free_list_end; /* Free List End pointer */
55Q_BUF_ptr_ptr q_free_list_ptr ; /* Ptr to Q_BUF variable */
56BYTE_ptr unit_id_ptr ; /* Unit Id */
57LPB_ptr link_str_ptr ; /* Link Structure Array */
58BYTE_ptr bootloader_1 ; /* 1st Stage Boot Loader */
59BYTE_ptr bootloader_2 ; /* 2nd Stage Boot Loader */
60WORD_ptr port_route_map_ptr ; /* Port Route Map */
61ROUTE_STR_ptr route_ptr ; /* Unit Route Map */
62NUMBER_ptr map_present ; /* Route Map present */
63NUMBER pkt_num ; /* Total number of packets */
64NUMBER q_num ; /* Total number of Q packets */
65WORD buffers_per_port ; /* Number of buffers per port */
66WORD heap_size ; /* Initial size of heap */
67WORD heap_left ; /* Current Heap left */
68WORD error ; /* Error code */
69WORD tx_max; /* Max number of tx pkts per phb */
70WORD rx_max; /* Max number of rx pkts per phb */
71WORD rx_limit; /* For high / low watermarks */
72NUMBER links ; /* Links to use */
73NUMBER timer ; /* Interrupts per second */
74RUP_ptr rups ; /* Pointer to the RUPs */
75WORD max_phb ; /* Mostly for debugging */
76WORD living ; /* Just increments!! */
77WORD init_done ; /* Initialisation over */
78WORD booting_link ;
79WORD idle_count ; /* Idle time counter */
80WORD busy_count ; /* Busy counter */
81WORD idle_control ; /* Control Idle Process */
82#if defined(HOST) || defined(INKERNEL)
83WORD tx_intr; /* TX interrupt pending */
84WORD rx_intr; /* RX interrupt pending */
85WORD rup_intr; /* RUP interrupt pending */
86#endif
87#if defined(RTA)
88WORD dying_count; /* Count of processes dead */
89#endif
90} ;
91
92#endif
93
94/*********** end of file ***********/
95
96
diff --git a/drivers/char/rio/pci.h b/drivers/char/rio/pci.h
new file mode 100644
index 000000000000..dc635bd25194
--- /dev/null
+++ b/drivers/char/rio/pci.h
@@ -0,0 +1,76 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : pci.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:12
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)pci.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_pci_h__
34#define __rio_pci_h__
35
36#ifdef SCCS_LABELS
37static char *_pci_h_sccs_ = "@(#)pci.h 1.2";
38#endif
39
40/*
41** PCI stuff
42*/
43
44#define PCITpFastClock 0x80
45#define PCITpSlowClock 0x00
46#define PCITpFastLinks 0x40
47#define PCITpSlowLinks 0x00
48#define PCITpIntEnable 0x04
49#define PCITpIntDisable 0x00
50#define PCITpBusEnable 0x02
51#define PCITpBusDisable 0x00
52#define PCITpBootFromRam 0x01
53#define PCITpBootFromLink 0x00
54
55#define RIO_PCI_VENDOR 0x11CB
56#define RIO_PCI_DEVICE 0x8000
57#define RIO_PCI_BASE_CLASS 0x02
58#define RIO_PCI_SUB_CLASS 0x80
59#define RIO_PCI_PROG_IFACE 0x00
60
61#define RIO_PCI_RID 0x0008
62#define RIO_PCI_BADR0 0x0010
63#define RIO_PCI_INTLN 0x003C
64#define RIO_PCI_INTPIN 0x003D
65
66#define RIO_PCI_MEM_SIZE 65536
67
68#define RIO_PCI_TURBO_TP 0x80
69#define RIO_PCI_FAST_LINKS 0x40
70#define RIO_PCI_INT_ENABLE 0x04
71#define RIO_PCI_TP_BUS_ENABLE 0x02
72#define RIO_PCI_BOOT_FROM_RAM 0x01
73
74#define RIO_PCI_DEFAULT_MODE 0x05
75
76#endif /* __rio_pci_h__ */
diff --git a/drivers/char/rio/phb.h b/drivers/char/rio/phb.h
new file mode 100644
index 000000000000..e1483a0e30bd
--- /dev/null
+++ b/drivers/char/rio/phb.h
@@ -0,0 +1,293 @@
1/****************************************************************************
2 ******* *******
3 ******* P H B H E A D E R *******
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra, Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _phb_h
38#define _phb_h 1
39
40#ifdef SCCS_LABELS
41#ifndef lint
42/* static char *_rio_phb_h_sccs = "@(#)phb.h 1.12"; */
43#endif
44#endif
45
46
47 /*************************************************
48 * Set the LIMIT values.
49 ************************************************/
50#ifdef RTA
51#define RX_LIMIT (ushort) 3
52#endif
53#ifdef HOST
54#define RX_LIMIT (ushort) 1
55#endif
56
57
58/*************************************************
59 * Handshake asserted. Deasserted by the LTT(s)
60 ************************************************/
61#define PHB_HANDSHAKE_SET ((ushort) 0x001) /* Set by LRT */
62
63#define PHB_HANDSHAKE_RESET ((ushort) 0x002) /* Set by ISR / driver */
64
65#define PHB_HANDSHAKE_FLAGS (PHB_HANDSHAKE_RESET | PHB_HANDSHAKE_SET)
66 /* Reset by ltt */
67
68
69/*************************************************
70 * Maximum number of PHB's
71 ************************************************/
72#if defined (HOST) || defined (INKERNEL)
73#define MAX_PHB ((ushort) 128) /* range 0-127 */
74#else
75#define MAX_PHB ((ushort) 8) /* range 0-7 */
76#endif
77
78/*************************************************
79 * Defines for the mode fields
80 ************************************************/
81#define TXPKT_INCOMPLETE 0x0001 /* Previous tx packet not completed */
82#define TXINTR_ENABLED 0x0002 /* Tx interrupt is enabled */
83#define TX_TAB3 0x0004 /* TAB3 mode */
84#define TX_OCRNL 0x0008 /* OCRNL mode */
85#define TX_ONLCR 0x0010 /* ONLCR mode */
86#define TX_SENDSPACES 0x0020 /* Send n spaces command needs
87 completing */
88#define TX_SENDNULL 0x0040 /* Escaping NULL needs completing */
89#define TX_SENDLF 0x0080 /* LF -> CR LF needs completing */
90#define TX_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel
91 port */
92#define TX_HANGOVER (TX_SENDSPACES | TX_SENDLF | TX_SENDNULL)
93#define TX_DTRFLOW 0x0200 /* DTR tx flow control */
94#define TX_DTRFLOWED 0x0400 /* DTR is low - don't allow more data
95 into the FIFO */
96#define TX_DATAINFIFO 0x0800 /* There is data in the FIFO */
97#define TX_BUSY 0x1000 /* Data in FIFO, shift or holding regs */
98
99#define RX_SPARE 0x0001 /* SPARE */
100#define RXINTR_ENABLED 0x0002 /* Rx interrupt enabled */
101#define RX_ICRNL 0x0008 /* ICRNL mode */
102#define RX_INLCR 0x0010 /* INLCR mode */
103#define RX_IGNCR 0x0020 /* IGNCR mode */
104#define RX_CTSFLOW 0x0040 /* CTSFLOW enabled */
105#define RX_IXOFF 0x0080 /* IXOFF enabled */
106#define RX_CTSFLOWED 0x0100 /* CTSFLOW and CTS dropped */
107#define RX_IXOFFED 0x0200 /* IXOFF and xoff sent */
108#define RX_BUFFERED 0x0400 /* Try and pass on complete packets */
109
110#define PORT_ISOPEN 0x0001 /* Port open? */
111#define PORT_HUPCL 0x0002 /* Hangup on close? */
112#define PORT_MOPENPEND 0x0004 /* Modem open pending */
113#define PORT_ISPARALLEL 0x0008 /* Parallel port */
114#define PORT_BREAK 0x0010 /* Port on break */
115#define PORT_STATUSPEND 0x0020 /* Status packet pending */
116#define PORT_BREAKPEND 0x0040 /* Break packet pending */
117#define PORT_MODEMPEND 0x0080 /* Modem status packet pending */
118#define PORT_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel
119 port */
120#define PORT_FULLMODEM 0x0200 /* Full modem signals */
121#define PORT_RJ45 0x0400 /* RJ45 connector - no RI signal */
122#define PORT_RESTRICTED 0x0600 /* Restricted connector - no RI / DTR */
123
124#define PORT_MODEMBITS 0x0600 /* Mask for modem fields */
125
126#define PORT_WCLOSE 0x0800 /* Waiting for close */
127#define PORT_HANDSHAKEFIX 0x1000 /* Port has H/W flow control fix */
128#define PORT_WASPCLOSED 0x2000 /* Port closed with PCLOSE */
129#define DUMPMODE 0x4000 /* Dump RTA mem */
130#define READ_REG 0x8000 /* Read CD1400 register */
131
132
133
134/**************************************************************************
135 * PHB Structure
136 * A few words.
137 *
138 * Normally Packets are added to the end of the list and removed from
139 * the start. The pointer tx_add points to a SPACE to put a Packet.
140 * The pointer tx_remove points to the next Packet to remove
141 *************************************************************************/
142#ifndef INKERNEL
143#define src_unit u2.s2.unit
144#define src_port u2.s2.port
145#define dest_unit u1.s1.unit
146#define dest_port u1.s1.port
147#endif
148#ifdef HOST
149#define tx_start u3.s1.tx_start_ptr_ptr
150#define tx_add u3.s1.tx_add_ptr_ptr
151#define tx_end u3.s1.tx_end_ptr_ptr
152#define tx_remove u3.s1.tx_remove_ptr_ptr
153#define rx_start u4.s1.rx_start_ptr_ptr
154#define rx_add u4.s1.rx_add_ptr_ptr
155#define rx_end u4.s1.rx_end_ptr_ptr
156#define rx_remove u4.s1.rx_remove_ptr_ptr
157#endif
158typedef struct PHB PHB ;
159struct PHB {
160#ifdef RTA
161 ushort port;
162#endif
163#ifdef INKERNEL
164 WORD source;
165#else
166 union
167 {
168 ushort source; /* Complete source */
169 struct
170 {
171 unsigned char unit; /* Source unit */
172 unsigned char port; /* Source port */
173 } s2;
174 } u2;
175#endif
176 WORD handshake ;
177 WORD status ;
178 NUMBER timeout ; /* Maximum of 1.9 seconds */
179 WORD link ; /* Send down this link */
180#ifdef INKERNEL
181 WORD destination;
182#else
183 union
184 {
185 ushort destination; /* Complete destination */
186 struct
187 {
188 unsigned char unit; /* Destination unit */
189 unsigned char port; /* Destination port */
190 } s1;
191 } u1;
192#endif
193#ifdef RTA
194 ushort tx_pkts_added;
195 ushort tx_pkts_removed;
196 Q_BUF_ptr tx_q_start ; /* Start of the Q list chain */
197 short num_tx_q_bufs ; /* Number of Q buffers in the chain */
198 PKT_ptr_ptr tx_add ; /* Add a new Packet here */
199 Q_BUF_ptr tx_add_qb; /* Pointer to the add Q buf */
200 PKT_ptr_ptr tx_add_st_qbb ; /* Pointer to start of the Q's buf */
201 PKT_ptr_ptr tx_add_end_qbb ; /* Pointer to the end of the Q's buf */
202 PKT_ptr_ptr tx_remove ; /* Remove a Packet here */
203 Q_BUF_ptr tx_remove_qb ; /* Pointer to the remove Q buf */
204 PKT_ptr_ptr tx_remove_st_qbb ; /* Pointer to the start of the Q buf */
205 PKT_ptr_ptr tx_remove_end_qbb ; /* Pointer to the end of the Q buf */
206#endif
207#ifdef INKERNEL
208 PKT_ptr_ptr tx_start ;
209 PKT_ptr_ptr tx_end ;
210 PKT_ptr_ptr tx_add ;
211 PKT_ptr_ptr tx_remove ;
212#endif
213#ifdef HOST
214 union
215 {
216 struct
217 {
218 PKT_ptr_ptr tx_start_ptr_ptr;
219 PKT_ptr_ptr tx_end_ptr_ptr;
220 PKT_ptr_ptr tx_add_ptr_ptr;
221 PKT_ptr_ptr tx_remove_ptr_ptr;
222 } s1;
223 struct
224 {
225 ushort * tx_start_ptr;
226 ushort * tx_end_ptr;
227 ushort * tx_add_ptr;
228 ushort * tx_remove_ptr;
229 } s2;
230 } u3;
231#endif
232
233#ifdef RTA
234 ushort rx_pkts_added;
235 ushort rx_pkts_removed;
236 Q_BUF_ptr rx_q_start ; /* Start of the Q list chain */
237 short num_rx_q_bufs ; /* Number of Q buffers in the chain */
238 PKT_ptr_ptr rx_add ; /* Add a new Packet here */
239 Q_BUF_ptr rx_add_qb ; /* Pointer to the add Q buf */
240 PKT_ptr_ptr rx_add_st_qbb ; /* Pointer to start of the Q's buf */
241 PKT_ptr_ptr rx_add_end_qbb ; /* Pointer to the end of the Q's buf */
242 PKT_ptr_ptr rx_remove ; /* Remove a Packet here */
243 Q_BUF_ptr rx_remove_qb ; /* Pointer to the remove Q buf */
244 PKT_ptr_ptr rx_remove_st_qbb ; /* Pointer to the start of the Q buf */
245 PKT_ptr_ptr rx_remove_end_qbb ; /* Pointer to the end of the Q buf */
246#endif
247#ifdef INKERNEL
248 PKT_ptr_ptr rx_start ;
249 PKT_ptr_ptr rx_end ;
250 PKT_ptr_ptr rx_add ;
251 PKT_ptr_ptr rx_remove ;
252#endif
253#ifdef HOST
254 union
255 {
256 struct
257 {
258 PKT_ptr_ptr rx_start_ptr_ptr;
259 PKT_ptr_ptr rx_end_ptr_ptr;
260 PKT_ptr_ptr rx_add_ptr_ptr;
261 PKT_ptr_ptr rx_remove_ptr_ptr;
262 } s1;
263 struct
264 {
265 ushort * rx_start_ptr;
266 ushort * rx_end_ptr;
267 ushort * rx_add_ptr;
268 ushort * rx_remove_ptr;
269 } s2;
270 } u4;
271#endif
272
273#ifdef RTA /* some fields for the remotes */
274 ushort flush_count; /* Count of write flushes */
275 ushort txmode; /* Modes for tx */
276 ushort rxmode; /* Modes for rx */
277 ushort portmode; /* Generic modes */
278 ushort column; /* TAB3 column count */
279 ushort tx_subscript; /* (TX) Subscript into data field */
280 ushort rx_subscript; /* (RX) Subscript into data field */
281 PKT_ptr rx_incomplete; /* Hold an incomplete packet here */
282 ushort modem_bits; /* Modem bits to mask */
283 ushort lastModem; /* Modem control lines. */
284 ushort addr; /* Address for sub commands */
285 ushort MonitorTstate; /* TRUE if monitoring tstop */
286#endif
287
288 } ;
289
290#endif
291
292/*********** end of file ***********/
293
diff --git a/drivers/char/rio/pkt.h b/drivers/char/rio/pkt.h
new file mode 100644
index 000000000000..66bb2ff0f694
--- /dev/null
+++ b/drivers/char/rio/pkt.h
@@ -0,0 +1,120 @@
1/****************************************************************************
2 ******* *******
3 ******* P A C K E T H E A D E R F I L E
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _pkt_h
38#define _pkt_h 1
39
40
41#ifdef SCCS_LABELS
42#ifndef lint
43/* static char *_rio_pkt_h_sccs = "@(#)pkt.h 1.8"; */
44#endif
45#endif
46
47#define MAX_TTL 0xf
48#define PKT_CMD_BIT ((ushort) 0x080)
49#define PKT_CMD_DATA ((ushort) 0x080)
50
51#define PKT_ACK ((ushort) 0x040)
52
53#define PKT_TGL ((ushort) 0x020)
54
55#define PKT_LEN_MASK ((ushort) 0x07f)
56
57#define DATA_WNDW ((ushort) 0x10)
58#define PKT_TTL_MASK ((ushort) 0x0f)
59
60#define PKT_MAX_DATA_LEN 72
61
62#define PKT_LENGTH sizeof(struct PKT)
63#define SYNC_PKT_LENGTH (PKT_LENGTH + 4)
64
65#define CONTROL_PKT_LEN_MASK PKT_LEN_MASK
66#define CONTROL_PKT_CMD_BIT PKT_CMD_BIT
67#define CONTROL_PKT_ACK (PKT_ACK << 8)
68#define CONTROL_PKT_TGL (PKT_TGL << 8)
69#define CONTROL_PKT_TTL_MASK (PKT_TTL_MASK << 8)
70#define CONTROL_DATA_WNDW (DATA_WNDW << 8)
71
72struct PKT {
73#ifdef INKERNEL
74 BYTE dest_unit ; /* Destination Unit Id */
75 BYTE dest_port ; /* Destination POrt */
76 BYTE src_unit ; /* Source Unit Id */
77 BYTE src_port ; /* Source POrt */
78#else
79 union
80 {
81 ushort destination; /* Complete destination */
82 struct
83 {
84 unsigned char unit; /* Destination unit */
85 unsigned char port; /* Destination port */
86 } s1;
87 } u1;
88 union
89 {
90 ushort source; /* Complete source */
91 struct
92 {
93 unsigned char unit; /* Source unit */
94 unsigned char port; /* Source port */
95 } s2;
96 } u2;
97#endif
98#ifdef INKERNEL
99 BYTE len ;
100 BYTE control;
101#else
102 union
103 {
104 ushort control;
105 struct
106 {
107 unsigned char len;
108 unsigned char control;
109 } s3;
110 } u3;
111#endif
112 BYTE data[PKT_MAX_DATA_LEN] ;
113 /* Actual data :-) */
114 WORD csum ; /* C-SUM */
115 } ;
116#endif
117
118/*********** end of file ***********/
119
120
diff --git a/drivers/char/rio/poll.h b/drivers/char/rio/poll.h
new file mode 100644
index 000000000000..d9b8e983e175
--- /dev/null
+++ b/drivers/char/rio/poll.h
@@ -0,0 +1,76 @@
1/****************************************************************************
2 ******* *******
3 ******* P O L L
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _poll_h
38#define _poll_h
39
40#ifndef lint
41#ifdef SCCS_LABELS
42static char *_rio_poll_h_sccs = "@(#)poll.h 1.2" ;
43#endif
44#endif
45
46
47#ifdef HOST
48#define POLL_STACK 100
49#endif
50#ifdef RTA
51#define POLL_STACK 200
52#endif
53
54#define POLL_PERIOD (int) SECOND
55
56/* The various poll commands */
57#define POLL_POLL 0 /* We are connected and happy.. */
58#define POLL_INTRO 1 /* Introduction packet */
59#define POLL_TOPOLOGY 2 /* Topology update */
60#define POLL_ASSIGN 3 /* ID assign */
61#define POLL_FOAD 4 /* F*** Off And Die */
62#define POLL_LMD 5 /* Let Me Die */
63#define POLL_DYB 6 /* Die You Ba***** */
64
65/* The way data fields are split up for POLL packets */
66#define POLL_HOST_SERIAL 2 /* Host who booted me */
67#define POLL_MY_SERIAL 6 /* My serial number */
68#define POLL_YOUR_ID 1 /* Your ID number */
69#define POLL_TOPOLOGY_FIELDS 2 /* Topology maps */
70
71#endif
72
73/*********** end of file ***********/
74
75
76
diff --git a/drivers/char/rio/port.h b/drivers/char/rio/port.h
new file mode 100644
index 000000000000..8506af06aa9f
--- /dev/null
+++ b/drivers/char/rio/port.h
@@ -0,0 +1,245 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : port.h
24** SID : 1.3
25** Last Modified : 11/6/98 11:34:12
26** Retrieved : 11/6/98 11:34:21
27**
28** ident @(#)port.h 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_port_h__
34#define __rio_port_h__
35
36#ifdef SCCS_LABELS
37static char *_port_h_sccs_ = "@(#)port.h 1.3";
38#endif
39
40
41#undef VPIX
42
43
44/*
45** the port data structure - one per port in the system
46*/
47
48#ifdef STATS
49struct RIOStats
50{
51 /*
52 ** interrupt statistics
53 */
54 uint BreakIntCnt;
55 uint ModemOffCnt;
56 uint ModemOnCnt;
57 uint RxIntCnt;
58 uint TxIntCnt;
59 /*
60 ** throughput statistics
61 */
62 uint RxCharCnt;
63 uint RxPktCnt;
64 uint RxSaveCnt;
65 uint TxCharCnt;
66 uint TxPktCnt;
67 /*
68 ** driver entry statistics
69 */
70 uint CloseCnt;
71 uint IoctlCnt;
72 uint OpenCnt;
73 uint ReadCnt;
74 uint WriteCnt;
75 /*
76 ** proc statistics
77 */
78 uint BlockCnt;
79 uint OutputCnt;
80 uint ResumeCnt;
81 uint RflushCnt;
82 uint SuspendCnt;
83 uint TbreakCnt;
84 uint TimeoutCnt;
85 uint UnblockCnt;
86 uint WflushCnt;
87 uint WFBodgeCnt;
88};
89#endif
90
91/*
92** Port data structure
93*/
94struct Port
95{
96 struct gs_port gs;
97 int PortNum; /* RIO port no., 0-511 */
98 struct Host *HostP;
99 volatile caddr_t Caddr;
100 ushort HostPort; /* Port number on host card */
101 uchar RupNum; /* Number of RUP for port */
102 uchar ID2; /* Second ID of RTA for port */
103 ulong State; /* FLAGS for open & xopen */
104#define RIO_LOPEN 0x00001 /* Local open */
105#define RIO_MOPEN 0x00002 /* Modem open */
106#define RIO_WOPEN 0x00004 /* Waiting for open */
107#define RIO_CLOSING 0x00008 /* The port is being close */
108#define RIO_XPBUSY 0x00010 /* Transparent printer busy */
109#define RIO_BREAKING 0x00020 /* Break in progress */
110#define RIO_DIRECT 0x00040 /* Doing Direct output */
111#define RIO_EXCLUSIVE 0x00080 /* Stream open for exclusive use */
112#define RIO_NDELAY 0x00100 /* Stream is open FNDELAY */
113#define RIO_CARR_ON 0x00200 /* Stream has carrier present */
114#define RIO_XPWANTR 0x00400 /* Stream wanted by Xprint */
115#define RIO_RBLK 0x00800 /* Stream is read-blocked */
116#define RIO_BUSY 0x01000 /* Stream is BUSY for write */
117#define RIO_TIMEOUT 0x02000 /* Stream timeout in progress */
118#define RIO_TXSTOP 0x04000 /* Stream output is stopped */
119#define RIO_WAITFLUSH 0x08000 /* Stream waiting for flush */
120#define RIO_DYNOROD 0x10000 /* Drain failed */
121#define RIO_DELETED 0x20000 /* RTA has been deleted */
122#define RIO_ISSCANCODE 0x40000 /* This line is in scancode mode */
123#define RIO_USING_EUC 0x100000 /* Using extended Unix chars */
124#define RIO_CAN_COOK 0x200000 /* This line can do cooking */
125#define RIO_TRIAD_MODE 0x400000 /* Enable TRIAD special ops. */
126#define RIO_TRIAD_BLOCK 0x800000 /* Next read will block */
127#define RIO_TRIAD_FUNC 0x1000000 /* Seen a function key coming in */
128#define RIO_THROTTLE_RX 0x2000000 /* RX needs to be throttled. */
129
130 ulong Config; /* FLAGS for NOREAD.... */
131#define RIO_NOREAD 0x0001 /* Are not allowed to read port */
132#define RIO_NOWRITE 0x0002 /* Are not allowed to write port */
133#define RIO_NOXPRINT 0x0004 /* Are not allowed to xprint port */
134#define RIO_NOMASK 0x0007 /* All not allowed things */
135#define RIO_IXANY 0x0008 /* Port is allowed ixany */
136#define RIO_MODEM 0x0010 /* Stream is a modem device */
137#define RIO_IXON 0x0020 /* Port is allowed ixon */
138#define RIO_WAITDRAIN 0x0040 /* Wait for port to completely drain */
139#define RIO_MAP_50_TO_50 0x0080 /* Map 50 baud to 50 baud */
140#define RIO_MAP_110_TO_110 0x0100 /* Map 110 baud to 110 baud */
141
142/*
143** 15.10.1998 ARG - ESIL 0761 prt fix
144** As LynxOS does not appear to support Hardware Flow Control .....
145** Define our own flow control flags in 'Config'.
146*/
147#define RIO_CTSFLOW 0x0200 /* RIO's own CTSFLOW flag */
148#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */
149
150
151 struct PHB *PhbP; /* pointer to PHB for port */
152 WORD *TxAdd; /* Add packets here */
153 WORD *TxStart; /* Start of add array */
154 WORD *TxEnd; /* End of add array */
155 WORD *RxRemove; /* Remove packets here */
156 WORD *RxStart; /* Start of remove array */
157 WORD *RxEnd; /* End of remove array */
158 uint RtaUniqueNum; /* Unique number of RTA */
159 ushort PortState; /* status of port */
160 ushort ModemState; /* status of modem lines */
161 ulong ModemLines; /* Modem bits sent to RTA */
162 uchar CookMode; /* who expands CR/LF? */
163 uchar ParamSem; /* Prevent write during param */
164 uchar Mapped; /* if port mapped onto host */
165 uchar SecondBlock; /* if port belongs to 2nd block
166 of 16 port RTA */
167 uchar InUse; /* how many pre-emptive cmds */
168 uchar Lock; /* if params locked */
169 uchar Store; /* if params stored across closes */
170 uchar FirstOpen; /* TRUE if first time port opened */
171 uchar FlushCmdBodge; /* if doing a (non)flush */
172 uchar MagicFlags; /* require intr processing */
173#define MAGIC_FLUSH 0x01 /* mirror of WflushFlag */
174#define MAGIC_REBOOT 0x02 /* RTA re-booted, re-open ports */
175#define MORE_OUTPUT_EYGOR 0x04 /* riotproc failed to empty clists */
176 uchar WflushFlag; /* 1 How many WFLUSHs active */
177/*
178** Transparent print stuff
179*/
180 struct Xprint
181 {
182#ifndef MAX_XP_CTRL_LEN
183#define MAX_XP_CTRL_LEN 16 /* ALSO IN DAEMON.H */
184#endif
185 uint XpCps;
186 char XpOn[MAX_XP_CTRL_LEN];
187 char XpOff[MAX_XP_CTRL_LEN];
188 ushort XpLen; /* strlen(XpOn)+strlen(XpOff) */
189 uchar XpActive;
190 uchar XpLastTickOk; /* TRUE if we can process */
191#define XP_OPEN 00001
192#define XP_RUNABLE 00002
193 struct ttystatics *XttyP;
194 } Xprint;
195#ifdef VPIX
196 v86_t *StashP;
197 uint IntMask;
198 struct termss VpixSs;
199 uchar ModemStatusReg; /* Modem status register */
200#endif
201 uchar RxDataStart;
202 uchar Cor2Copy; /* copy of COR2 */
203 char *Name; /* points to the Rta's name */
204#ifdef STATS
205 struct RIOStats Stat; /* ports statistics */
206#endif
207 char *TxRingBuffer;
208 ushort TxBufferIn; /* New data arrives here */
209 ushort TxBufferOut; /* Intr removes data here */
210 ushort OldTxBufferOut; /* Indicates if draining */
211 int TimeoutId; /* Timeout ID */
212 uint Debug;
213 uchar WaitUntilBooted; /* True if open should block */
214 uint statsGather; /* True if gathering stats */
215 ulong txchars; /* Chars transmitted */
216 ulong rxchars; /* Chars received */
217 ulong opens; /* port open count */
218 ulong closes; /* port close count */
219 ulong ioctls; /* ioctl count */
220 uchar LastRxTgl; /* Last state of rx toggle bit */
221 spinlock_t portSem; /* Lock using this sem */
222 int MonitorTstate; /* Monitoring ? */
223 int timeout_id; /* For calling 100 ms delays */
224 int timeout_sem;/* For calling 100 ms delays */
225 int firstOpen; /* First time open ? */
226 char * p; /* save the global struc here .. */
227};
228
229struct ModuleInfo
230{
231 char *Name;
232 uint Flags[4]; /* one per port on a module */
233};
234#endif
235
236/*
237** This struct is required because trying to grab an entire Port structure
238** runs into problems with differing struct sizes between driver and config.
239*/
240struct PortParams {
241 uint Port;
242 ulong Config;
243 ulong State;
244 struct ttystatics *TtyP;
245};
diff --git a/drivers/char/rio/proto.h b/drivers/char/rio/proto.h
new file mode 100644
index 000000000000..ddff0ef84e3a
--- /dev/null
+++ b/drivers/char/rio/proto.h
@@ -0,0 +1,244 @@
1/*
2 *
3 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#ifndef _prototypes_h
20#define _prototypes_h
21
22
23/*
24** boot.c
25*/
26void init_boot( char *p, short stage);
27
28/*
29** disconct.c
30*/
31void kill_boot ( LPB *link );
32void disconnected( LPB *link );
33short boot_3( LPB *link, PKT *pkt );
34short send_3_pkt( LPB *link, PKT *pkt);
35
36/*
37** error.c
38*/
39void du_error(void);
40
41/*
42** formpkt.c
43*/
44ushort sum_it( PKT *pkt ) ;
45void form_rup_pkt( RUP *form_rup, PKT *pkt );
46void form_poll_pkt ( int type, LPB *link, int node );
47void form_route_pkt ( int type, PKT *pkt, LPB *link );
48
49/*
50** idle.c
51*/
52void idle( Process *idle_p );
53
54/*
55** init.c
56*/
57void general_init(void);
58void mem_halt( int error);
59
60/*
61** linkinit.c
62*/
63void initlink( u_short number, LPB *link);
64void runlink( LPB *link);
65
66/*
67** list.c
68*/
69PKT *get_free_start(void);
70void put_free_start( PKT *pkt);
71
72#ifdef HOST
73int can_remove_transmit ( PKT **pkt, PKT *pointer );
74#endif
75
76#ifdef RTA
77int spl7 ( void );
78int spl0 ( void );
79Q_BUF *get_free_q( void );
80PKT *get_free_end(void);
81int add_end( PKT *pkt, PHB *phb, int type);
82unsigned short free_packets( PHB *phb, int type);
83int can_remove_start( PKT **pkt, PHB *phb, int type);
84int can_add_start( PHB *phb, int type);
85int can_add_end( PHB *phb, int type);
86void put_free_end( PKT *pkt);
87int remove_start( PKT **pkt, PHB *phb, int type);
88#endif
89
90/*
91** Lrt.c
92*/
93void lrt( Process *lrt_p, LPB *link );
94
95#ifdef RTA
96void set_led_red ( LPB *link );
97#endif
98
99/*
100** ltt.c
101*/
102void ltt( Process *ltt_p, LPB *link, PHB *phb_ptr[] );
103void send_poll ( LPB *link );
104void request_id ( LPB *link );
105void send_topology_update ( LPB *link );
106void send_topology ( LPB *link );
107void supply_id ( LPB *link );
108
109#ifdef RTA
110void redirect_queue ( LPB *link, ushort flush );
111int obtain_rup ( int rup_number, PKT **pkt_address, LPB *link );
112#endif
113
114#ifdef TESTING_PERF
115int consume_cpu( void );
116#endif
117
118/*
119** lttwake.c
120*/
121#ifdef HOST
122void ltt_wakeup( Process *ltt_wakeup_p );
123#endif
124
125/*
126** mapgen.c
127*/
128void generate_id_map( short mapping, ROUTE_STR route[] );
129void gen_map( int mapping, int looking_at, int come_from, ROUTE_STR route[], int link, int *ttl );
130void adjust_ttl( int mapping, int looking_at, int come_from, ROUTE_STR route[], int link, int *ttl);
131void init_sys_map(void);
132
133/*
134** mmu.c
135*/
136char *rio_malloc( unsigned int amount);
137char *rio_calloc( unsigned int num, unsigned int size);
138ERROR rio_mmu_init( uint total_mem );
139
140/*
141** partn.c
142*/
143void partition_tx( struct PHB *phb, u_short tx_size, u_short rx_size, u_short rx_limit);
144
145/*
146** poll.c
147*/
148void tx_poll( Process *tx_poll_p);
149
150/*
151** process.c
152*/
153int get_proc_space( Process **pd, int **pws, int wssize);
154
155/*
156** readrom.c
157*/
158void read_serial_number(char *buf);
159
160/*
161** rio.c
162*/
163int main( void );
164
165/*
166** route.c
167*/
168void route_update ( PKT *pkt, LPB *link);
169
170/*
171** rtainit.c
172*/
173#if defined(RTA)
174void rta_init(ushort RtaType);
175#endif /* defined(RTA) */
176
177/*
178** rupboot.c
179*/
180void rup_boot( PKT *pkt, RUP *this_rup, LPB *link);
181
182#ifdef RTA
183void kill_your_neighbour( int link_to_kill );
184#endif
185
186/*
187** rupcmd.c
188*/
189void rup_command( PKT *pkt, struct RUP *this_rup, LPB *link);
190
191/*
192** ruperr.c
193*/
194void rup_error( PKT *pkt, RUP *this_rup, LPB *link );
195void illegal_cmd( PKT *src_pkt );
196
197/*
198** ruppoll.c
199*/
200void rup_poll( PKT *pkt, RUP *this_rup, LPB *link );
201
202/*
203** ruppower.c
204*/
205void rup_power( PKT *pkt, RUP *this_rup, LPB *link );
206
207/*
208** ruprm.c
209*/
210void rup_route_map( PKT *pkt, RUP *this_rup, LPB *link);
211
212/*
213** rupstat.c
214*/
215void rup_status( PKT *pkt, RUP *this_rup, LPB *link);
216
217/*
218** rupsync.c
219*/
220void rup_sync( PKT *pkt);
221
222/*
223** rxpkt.c
224*/
225ERROR rx_pkt( PKT_ptr_ptr pkt_address, LPB *link);
226
227/*
228** sendsts.c
229*/
230void send_status( PKT *requesting_pkt, RUP *this_rup);
231
232/*
233** serial.c
234*/
235void assign_serial ( char *ser_in, char *ser_out);
236int cmp_serial ( char *ser_1, char *ser_2);
237
238/*
239** txpkt.c
240*/
241ERROR tx_pkt( PKT *pkt, LPB *link);
242short send_sync( LPB *link);
243
244#endif /* _prototypes_h */
diff --git a/drivers/char/rio/protsts.h b/drivers/char/rio/protsts.h
new file mode 100644
index 000000000000..848111ac9380
--- /dev/null
+++ b/drivers/char/rio/protsts.h
@@ -0,0 +1,119 @@
1/****************************************************************************
2 ******* *******
3 ******* P R O T O C O L S T A T U S S T R U C T U R E *******
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _protsts_h
38#define _protsts_h 1
39
40
41#ifdef SCCS_LABELS
42#ifndef lint
43/* static char *_rio_protsts_h_sccs = "@(#)protsts.h 1.4"; */
44#endif
45#endif
46
47/*************************************************
48 * ACK bit. Last Packet received OK. Set by
49 * rxpkt to indicate that the Packet has been
50 * received OK and that the LTT must set the ACK
51 * bit in the next outward bound Packet
52 * and re-set by LTT's after xmit.
53 *
54 * Gets shoved into rx_status
55 ************************************************/
56#define PHB_RX_LAST_PKT_ACKED ((ushort) 0x080)
57
58/*******************************************************
59 * The Rx TOGGLE bit.
60 * Stuffed into rx_status by RXPKT
61 ******************************************************/
62#define PHB_RX_DATA_WNDW ((ushort) 0x040)
63
64/*******************************************************
65 * The Rx TOGGLE bit. Matches the setting in PKT.H
66 * Stuffed into rx_status
67 ******************************************************/
68#define PHB_RX_TGL ((ushort) 0x2000)
69
70
71/*************************************************
72 * This bit is set by the LRT to indicate that
73 * an ACK (packet) must be returned.
74 *
75 * Gets shoved into tx_status
76 ************************************************/
77#define PHB_TX_SEND_PKT_ACK ((ushort) 0x08)
78
79/*************************************************
80 * Set by LTT to indicate that an ACK is required
81 *************************************************/
82#define PHB_TX_ACK_RQRD ((ushort) 0x01)
83
84
85/*******************************************************
86 * The Tx TOGGLE bit.
87 * Stuffed into tx_status by RXPKT from the PKT WndW
88 * field. Looked by the LTT when the NEXT Packet
89 * is going to be sent.
90 ******************************************************/
91#define PHB_TX_DATA_WNDW ((ushort) 0x04)
92
93
94/*******************************************************
95 * The Tx TOGGLE bit. Matches the setting in PKT.H
96 * Stuffed into tx_status
97 ******************************************************/
98#define PHB_TX_TGL ((ushort) 0x02)
99
100/*******************************************************
101 * Request intr bit. Set when the queue has gone quiet
102 * and the PHB has requested an interrupt.
103 ******************************************************/
104#define PHB_TX_INTR ((ushort) 0x100)
105
106/*******************************************************
107 * SET if the PHB cannot send any more data down the
108 * Link
109 ******************************************************/
110#define PHB_TX_HANDSHAKE ((ushort) 0x010)
111
112
113#define RUP_SEND_WNDW ((ushort) 0x08) ;
114
115#endif
116
117/*********** end of file ***********/
118
119
diff --git a/drivers/char/rio/qbuf.h b/drivers/char/rio/qbuf.h
new file mode 100644
index 000000000000..1fce02f8fcfc
--- /dev/null
+++ b/drivers/char/rio/qbuf.h
@@ -0,0 +1,67 @@
1
2/****************************************************************************
3 ******* *******
4 ******* Q U E U E B U F F E R S T R U C T U R E S
5 ******* *******
6 ****************************************************************************
7
8 Author : Ian Nandhra / Jeremy Rolls
9 Date :
10
11 *
12 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 Version : 0.01
29
30
31 Mods
32 ----------------------------------------------------------------------------
33 Date By Description
34 ----------------------------------------------------------------------------
35
36 ***************************************************************************/
37
38#ifndef _qbuf_h
39#define _qbuf_h 1
40
41#ifndef lint
42#ifdef SCCS_LABELS
43static char *_rio_qbuf_h_sccs = "@(#)qbuf.h 1.1" ;
44#endif
45#endif
46
47
48
49#ifdef HOST
50#define PKTS_PER_BUFFER 1
51#else
52#define PKTS_PER_BUFFER (220 / PKT_LENGTH)
53#endif
54
55typedef struct Q_BUF Q_BUF ;
56struct Q_BUF {
57 Q_BUF_ptr next ;
58 Q_BUF_ptr prev ;
59 PKT_ptr buf[PKTS_PER_BUFFER] ;
60 } ;
61
62
63#endif
64
65
66/*********** end of file ***********/
67
diff --git a/drivers/char/rio/rio.h b/drivers/char/rio/rio.h
new file mode 100644
index 000000000000..13a9931958b1
--- /dev/null
+++ b/drivers/char/rio/rio.h
@@ -0,0 +1,294 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 1998 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rio.h
24** SID : 1.3
25** Last Modified : 11/6/98 11:34:13
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)rio.h 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_rio_h__
34#define __rio_rio_h__
35
36#ifdef SCCS_LABELS
37static char *_rio_h_sccs_ = "@(#)rio.h 1.3";
38#endif
39
40/*
41** 30.09.1998 ARG -
42** Introduced driver version and host card type strings
43*/
44#define RIO_DRV_STR "Specialix RIO Driver"
45#define RIO_AT_HOST_STR "ISA"
46#define RIO_PCI_HOST_STR "PCI"
47
48
49/*
50** rio_info_store() commands (arbitary values) :
51*/
52#define RIO_INFO_PUT 0xA4B3C2D1
53#define RIO_INFO_GET 0xF1E2D3C4
54
55
56/*
57** anything that I couldn't cram in somewhere else
58*/
59/*
60#ifndef RIODEBUG
61#define debug
62#else
63#define debug rioprint
64#endif
65*/
66
67
68/*
69** Maximum numbers of things
70*/
71#define RIO_SLOTS 4 /* number of configuration slots */
72#define RIO_HOSTS 4 /* number of hosts that can be found */
73#define PORTS_PER_HOST 128 /* number of ports per host */
74#define LINKS_PER_UNIT 4 /* number of links from a host */
75#define RIO_PORTS (PORTS_PER_HOST * RIO_HOSTS) /* max. no. of ports */
76#define RTAS_PER_HOST (MAX_RUP) /* number of RTAs per host */
77#define PORTS_PER_RTA (PORTS_PER_HOST/RTAS_PER_HOST) /* ports on a rta */
78#define PORTS_PER_MODULE 4 /* number of ports on a plug-in module */
79 /* number of modules on an RTA */
80#define MODULES_PER_RTA (PORTS_PER_RTA/PORTS_PER_MODULE)
81#define MAX_PRODUCT 16 /* numbr of different product codes */
82#define MAX_MODULE_TYPES 16 /* number of different types of module */
83
84#define RIO_CONTROL_DEV 128 /* minor number of host/control device */
85#define RIO_INVALID_MAJOR 0 /* test first host card's major no for validity */
86
87/*
88** number of RTAs that can be bound to a master
89*/
90#define MAX_RTA_BINDINGS (MAX_RUP * RIO_HOSTS)
91
92/*
93** Unit types
94*/
95#define PC_RTA16 0x90000000
96#define PC_RTA8 0xe0000000
97#define TYPE_HOST 0
98#define TYPE_RTA8 1
99#define TYPE_RTA16 2
100
101/*
102** Flag values returned by functions
103*/
104#define RIO_FAIL -1
105#define RIO_SUCCESS 0
106#define COPYFAIL -1 /* copy[in|out] failed */
107
108/*
109** SysPort value for something that hasn't any ports
110*/
111#define NO_PORT 0xFFFFFFFF
112
113/*
114** Unit ID Of all hosts
115*/
116#define HOST_ID 0
117
118/*
119** Break bytes into nybles
120*/
121#define LONYBLE(X) ((X) & 0xF)
122#define HINYBLE(X) (((X)>>4) & 0xF)
123
124/*
125** Flag values passed into some functions
126*/
127#define DONT_SLEEP 0
128#define OK_TO_SLEEP 1
129
130#define DONT_PRINT 1
131#define DO_PRINT 0
132
133#define PRINT_TO_LOG_CONS 0
134#define PRINT_TO_CONS 1
135#define PRINT_TO_LOG 2
136
137/*
138** Timeout has trouble with times of less than 3 ticks...
139*/
140#define MIN_TIMEOUT 3
141
142/*
143** Generally useful constants
144*/
145#define HALF_A_SECOND ((HZ)>>1)
146#define A_SECOND (HZ)
147#define HUNDRED_HZ ((HZ/100)?(HZ/100):1)
148#define FIFTY_HZ ((HZ/50)?(HZ/50):1)
149#define TWENTY_HZ ((HZ/20)?(HZ/20):1)
150#define TEN_HZ ((HZ/10)?(HZ/10):1)
151#define FIVE_HZ ((HZ/5)?(HZ/5):1)
152#define HUNDRED_MS TEN_HZ
153#define FIFTY_MS TWENTY_HZ
154#define TWENTY_MS FIFTY_HZ
155#define TEN_MS HUNDRED_HZ
156#define TWO_SECONDS ((A_SECOND)*2)
157#define FIVE_SECONDS ((A_SECOND)*5)
158#define TEN_SECONDS ((A_SECOND)*10)
159#define FIFTEEN_SECONDS ((A_SECOND)*15)
160#define TWENTY_SECONDS ((A_SECOND)*20)
161#define HALF_A_MINUTE (A_MINUTE>>1)
162#define A_MINUTE (A_SECOND*60)
163#define FIVE_MINUTES (A_MINUTE*5)
164#define QUARTER_HOUR (A_MINUTE*15)
165#define HALF_HOUR (A_MINUTE*30)
166#define HOUR (A_MINUTE*60)
167
168#define SIXTEEN_MEG 0x1000000
169#define ONE_MEG 0x100000
170#define SIXTY_FOUR_K 0x10000
171
172#define RIO_AT_MEM_SIZE SIXTY_FOUR_K
173#define RIO_EISA_MEM_SIZE SIXTY_FOUR_K
174#define RIO_MCA_MEM_SIZE SIXTY_FOUR_K
175
176#define POLL_VECTOR 0x100
177
178#define COOK_WELL 0
179#define COOK_MEDIUM 1
180#define COOK_RAW 2
181
182/*
183** Pointer manipulation stuff
184** RIO_PTR takes hostp->Caddr and the offset into the DP RAM area
185** and produces a UNIX caddr_t (pointer) to the object
186** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and
187** returns the offset into the DP RAM area.
188*/
189#define RIO_PTR(C,O) (((caddr_t)(C))+(0xFFFF&(O)))
190#define RIO_OFF(C,O) ((int)(O)-(int)(C))
191
192/*
193** How to convert from various different device number formats:
194** DEV is a dev number, as passed to open, close etc - NOT a minor
195** number!
196**
197** Note: LynxOS only gives us 8 bits for the device minor number,
198** so all this crap here to deal with 'modem' bits etc. is
199** just a load of irrelevant old bunkum!
200** This however does not stop us needing to define a value
201** for RIO_MODEMOFFSET which is required by the 'riomkdev'
202** utility in the New Config Utilities suite.
203*/
204/* 0-511: direct 512-1023: modem */
205#define RIO_MODEMOFFSET 0x200 /* doesn't mean anything */
206#define RIO_MODEM_MASK 0x1FF
207#define RIO_MODEM_BIT 0x200
208#define RIO_UNMODEM(DEV) (MINOR(DEV) & RIO_MODEM_MASK)
209#define RIO_ISMODEM(DEV) (MINOR(DEV) & RIO_MODEM_BIT)
210#define RIO_PORT(DEV,FIRST_MAJ) ( (MAJOR(DEV) - FIRST_MAJ) * PORTS_PER_HOST) \
211 + MINOR(DEV)
212
213#define splrio spltty
214
215#define RIO_IPL 5
216#define RIO_PRI (PZERO+10)
217#define RIO_CLOSE_PRI PZERO-1 /* uninterruptible sleeps for close */
218
219typedef struct DbInf
220{
221 uint Flag;
222 char Name[8];
223} DbInf;
224
225#ifndef TRUE
226#define TRUE (1==1)
227#endif
228#ifndef FALSE
229#define FALSE (!TRUE)
230#endif
231
232#define CSUM(pkt_ptr) (((ushort *)(pkt_ptr))[0] + ((ushort *)(pkt_ptr))[1] + \
233 ((ushort *)(pkt_ptr))[2] + ((ushort *)(pkt_ptr))[3] + \
234 ((ushort *)(pkt_ptr))[4] + ((ushort *)(pkt_ptr))[5] + \
235 ((ushort *)(pkt_ptr))[6] + ((ushort *)(pkt_ptr))[7] + \
236 ((ushort *)(pkt_ptr))[8] + ((ushort *)(pkt_ptr))[9] )
237
238/*
239** This happy little macro copies SIZE bytes of data from FROM to TO
240** quite well. SIZE must be a constant.
241*/
242#define CCOPY( FROM, TO, SIZE ) { *(struct s { char data[SIZE]; } *)(TO) = *(struct s *)(FROM); }
243
244/*
245** increment a buffer pointer modulo the size of the buffer...
246*/
247#define BUMP( P, I ) ((P) = (((P)+(I)) & RIOBufferMask))
248
249#define INIT_PACKET( PK, PP ) \
250{ \
251 *((uint *)PK) = PP->PacketInfo; \
252}
253
254#define RIO_LINK_ENABLE 0x80FF /* FF is a hack, mainly for Mips, to */
255 /* prevent a really stupid race condition. */
256
257#define NOT_INITIALISED 0
258#define INITIALISED 1
259
260#define NOT_POLLING 0
261#define POLLING 1
262
263#define NOT_CHANGED 0
264#define CHANGED 1
265
266#define NOT_INUSE 0
267
268#define DISCONNECT 0
269#define CONNECT 1
270
271
272/*
273** Machine types - these must NOT overlap with product codes 0-15
274*/
275#define RIO_MIPS_R3230 31
276#define RIO_MIPS_R4030 32
277
278#define RIO_IO_UNKNOWN -2
279
280#undef MODERN
281#define ERROR( E ) do { u.u_error = E; return OPENFAIL } while ( 0 )
282
283/* Defines for MPX line discipline routines */
284
285#define DIST_LINESW_OPEN 0x01
286#define DIST_LINESW_CLOSE 0x02
287#define DIST_LINESW_READ 0x04
288#define DIST_LINESW_WRITE 0x08
289#define DIST_LINESW_IOCTL 0x10
290#define DIST_LINESW_INPUT 0x20
291#define DIST_LINESW_OUTPUT 0x40
292#define DIST_LINESW_MDMINT 0x80
293
294#endif /* __rio_h__ */
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
new file mode 100644
index 000000000000..a91ae271cf0a
--- /dev/null
+++ b/drivers/char/rio/rio_linux.c
@@ -0,0 +1,1380 @@
1
2/* rio_linux.c -- Linux driver for the Specialix RIO series cards.
3 *
4 *
5 * (C) 1999 R.E.Wolff@BitWizard.nl
6 *
7 * Specialix pays for the development and support of this driver.
8 * Please DO contact support@specialix.co.uk if you require
9 * support. But please read the documentation (rio.txt) first.
10 *
11 *
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of
16 * the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be
19 * useful, but WITHOUT ANY WARRANTY; without even the implied
20 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21 * PURPOSE. See the GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public
24 * License along with this program; if not, write to the Free
25 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
26 * USA.
27 *
28 * Revision history:
29 * $Log: rio.c,v $
30 * Revision 1.1 1999/07/11 10:13:54 wolff
31 * Initial revision
32 *
33 * */
34
35#include <linux/module.h>
36#include <linux/config.h>
37#include <linux/kdev_t.h>
38#include <asm/io.h>
39#include <linux/kernel.h>
40#include <linux/sched.h>
41#include <linux/ioport.h>
42#include <linux/interrupt.h>
43#include <linux/errno.h>
44#include <linux/tty.h>
45#include <linux/tty_flip.h>
46#include <linux/mm.h>
47#include <linux/serial.h>
48#include <linux/fcntl.h>
49#include <linux/major.h>
50#include <linux/delay.h>
51#include <linux/pci.h>
52#include <linux/slab.h>
53#include <linux/miscdevice.h>
54#include <linux/init.h>
55
56#include <linux/generic_serial.h>
57#include <asm/uaccess.h>
58
59#if BITS_PER_LONG != 32
60# error FIXME: this driver only works on 32-bit platforms
61#endif
62
63#include "linux_compat.h"
64#include "typdef.h"
65#include "pkt.h"
66#include "daemon.h"
67#include "rio.h"
68#include "riospace.h"
69#include "top.h"
70#include "cmdpkt.h"
71#include "map.h"
72#include "riotypes.h"
73#include "rup.h"
74#include "port.h"
75#include "riodrvr.h"
76#include "rioinfo.h"
77#include "func.h"
78#include "errors.h"
79#include "pci.h"
80
81#include "parmmap.h"
82#include "unixrup.h"
83#include "board.h"
84#include "host.h"
85#include "error.h"
86#include "phb.h"
87#include "link.h"
88#include "cmdblk.h"
89#include "route.h"
90#include "control.h"
91#include "cirrus.h"
92#include "rioioctl.h"
93#include "param.h"
94#include "list.h"
95#include "sam.h"
96#include "protsts.h"
97#include "rioboard.h"
98
99
100#include "rio_linux.h"
101
102/* I don't think that this driver can handle more than 512 ports on
103one machine. Specialix specifies max 4 boards in one machine. I don't
104know why. If you want to try anyway you'll have to increase the number
105of boards in rio.h. You'll have to allocate more majors if you need
106more than 512 ports.... */
107
108#ifndef RIO_NORMAL_MAJOR0
109/* This allows overriding on the compiler commandline, or in a "major.h"
110 include or something like that */
111#define RIO_NORMAL_MAJOR0 154
112#define RIO_NORMAL_MAJOR1 156
113#endif
114
115#ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8
116#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000
117#endif
118
119#ifndef RIO_WINDOW_LEN
120#define RIO_WINDOW_LEN 0x10000
121#endif
122
123
124/* Configurable options:
125 (Don't be too sure that it'll work if you toggle them) */
126
127/* Am I paranoid or not ? ;-) */
128#undef RIO_PARANOIA_CHECK
129
130
131/* 20 -> 2000 per second. The card should rate-limit interrupts at 1000
132 Hz, but it is user configurable. I don't recommend going above 1000
133 Hz. The interrupt ratelimit might trigger if the interrupt is
134 shared with a very active other device.
135 undef this if you want to disable the check....
136*/
137#define IRQ_RATE_LIMIT 200
138
139#if 0
140/* Not implemented */
141/*
142 * The following defines are mostly for testing purposes. But if you need
143 * some nice reporting in your syslog, you can define them also.
144 */
145#define RIO_REPORT_FIFO
146#define RIO_REPORT_OVERRUN
147#endif
148
149
150/* These constants are derived from SCO Source */
151static struct Conf
152RIOConf =
153{
154 /* locator */ "RIO Config here",
155 /* startuptime */ HZ*2, /* how long to wait for card to run */
156 /* slowcook */ 0, /* TRUE -> always use line disc. */
157 /* intrpolltime */ 1, /* The frequency of OUR polls */
158 /* breakinterval */ 25, /* x10 mS XXX: units seem to be 1ms not 10! -- REW*/
159 /* timer */ 10, /* mS */
160 /* RtaLoadBase */ 0x7000,
161 /* HostLoadBase */ 0x7C00,
162 /* XpHz */ 5, /* number of Xprint hits per second */
163 /* XpCps */ 120, /* Xprint characters per second */
164 /* XpOn */ "\033d#", /* start Xprint for a wyse 60 */
165 /* XpOff */ "\024", /* end Xprint for a wyse 60 */
166 /* MaxXpCps */ 2000, /* highest Xprint speed */
167 /* MinXpCps */ 10, /* slowest Xprint speed */
168 /* SpinCmds */ 1, /* non-zero for mega fast boots */
169 /* First Addr */ 0x0A0000, /* First address to look at */
170 /* Last Addr */ 0xFF0000, /* Last address looked at */
171 /* BufferSize */ 1024, /* Bytes per port of buffering */
172 /* LowWater */ 256, /* how much data left before wakeup */
173 /* LineLength */ 80, /* how wide is the console? */
174 /* CmdTimeout */ HZ, /* how long a close command may take */
175};
176
177
178
179
180/* Function prototypes */
181
182static void rio_disable_tx_interrupts (void * ptr);
183static void rio_enable_tx_interrupts (void * ptr);
184static void rio_disable_rx_interrupts (void * ptr);
185static void rio_enable_rx_interrupts (void * ptr);
186static int rio_get_CD (void * ptr);
187static void rio_shutdown_port (void * ptr);
188static int rio_set_real_termios (void *ptr);
189static void rio_hungup (void *ptr);
190static void rio_close (void *ptr);
191static int rio_chars_in_buffer (void * ptr);
192static int rio_fw_ioctl (struct inode *inode, struct file *filp,
193 unsigned int cmd, unsigned long arg);
194static int rio_init_drivers(void);
195
196static void my_hd (void *addr, int len);
197
198static struct tty_driver *rio_driver, *rio_driver2;
199
200/* The name "p" is a bit non-descript. But that's what the rio-lynxos
201sources use all over the place. */
202struct rio_info *p;
203
204int rio_debug;
205
206
207/* You can have the driver poll your card.
208 - Set rio_poll to 1 to poll every timer tick (10ms on Intel).
209 This is used when the card cannot use an interrupt for some reason.
210*/
211static int rio_poll = 1;
212
213
214/* These are the only open spaces in my computer. Yours may have more
215 or less.... */
216static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000};
217
218#define NR_RIO_ADDRS (sizeof(rio_probe_addrs)/sizeof (int))
219
220
221/* Set the mask to all-ones. This alas, only supports 32 interrupts.
222 Some architectures may need more. -- Changed to LONG to
223 support up to 64 bits on 64bit architectures. -- REW 20/06/99 */
224long rio_irqmask = -1;
225
226MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
227MODULE_DESCRIPTION("RIO driver");
228MODULE_LICENSE("GPL");
229module_param(rio_poll, int, 0);
230module_param(rio_debug, int, 0644);
231module_param(rio_irqmask, long, 0);
232
233static struct real_driver rio_real_driver = {
234 rio_disable_tx_interrupts,
235 rio_enable_tx_interrupts,
236 rio_disable_rx_interrupts,
237 rio_enable_rx_interrupts,
238 rio_get_CD,
239 rio_shutdown_port,
240 rio_set_real_termios,
241 rio_chars_in_buffer,
242 rio_close,
243 rio_hungup,
244 NULL
245};
246
247/*
248 * Firmware loader driver specific routines
249 *
250 */
251
252static struct file_operations rio_fw_fops = {
253 .owner = THIS_MODULE,
254 .ioctl = rio_fw_ioctl,
255};
256
257static struct miscdevice rio_fw_device = {
258 RIOCTL_MISC_MINOR, "rioctl", &rio_fw_fops
259};
260
261
262
263
264
265#ifdef RIO_PARANOIA_CHECK
266
267/* This doesn't work. Who's paranoid around here? Not me! */
268
269static inline int rio_paranoia_check(struct rio_port const * port,
270 char *name, const char *routine)
271{
272
273 static const char *badmagic =
274 KERN_ERR "rio: Warning: bad rio port magic number for device %s in %s\n";
275 static const char *badinfo =
276 KERN_ERR "rio: Warning: null rio port for device %s in %s\n";
277
278 if (!port) {
279 printk (badinfo, name, routine);
280 return 1;
281 }
282 if (port->magic != RIO_MAGIC) {
283 printk (badmagic, name, routine);
284 return 1;
285 }
286
287 return 0;
288}
289#else
290#define rio_paranoia_check(a,b,c) 0
291#endif
292
293
294#ifdef DEBUG
295static void my_hd (void *ad, int len)
296{
297 int i, j, ch;
298 unsigned char *addr = ad;
299
300 for (i=0;i<len;i+=16) {
301 rio_dprintk (RIO_DEBUG_PARAM, "%08x ", (int) addr+i);
302 for (j=0;j<16;j++) {
303 rio_dprintk (RIO_DEBUG_PARAM, "%02x %s", addr[j+i], (j==7)?" ":"");
304 }
305 for (j=0;j<16;j++) {
306 ch = addr[j+i];
307 rio_dprintk (RIO_DEBUG_PARAM, "%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
308 }
309 rio_dprintk (RIO_DEBUG_PARAM, "\n");
310 }
311}
312#else
313#define my_hd(ad,len) do{/* nothing*/ } while (0)
314#endif
315
316
317/* Delay a number of jiffies, allowing a signal to interrupt */
318int RIODelay (struct Port *PortP, int njiffies)
319{
320 func_enter ();
321
322 rio_dprintk (RIO_DEBUG_DELAY, "delaying %d jiffies\n", njiffies);
323 msleep_interruptible(jiffies_to_msecs(njiffies));
324 func_exit();
325
326 if (signal_pending(current))
327 return RIO_FAIL;
328 else
329 return !RIO_FAIL;
330}
331
332
333/* Delay a number of jiffies, disallowing a signal to interrupt */
334int RIODelay_ni (struct Port *PortP, int njiffies)
335{
336 func_enter ();
337
338 rio_dprintk (RIO_DEBUG_DELAY, "delaying %d jiffies (ni)\n", njiffies);
339 msleep(jiffies_to_msecs(njiffies));
340 func_exit();
341 return !RIO_FAIL;
342}
343
344
345int rio_minor(struct tty_struct *tty)
346{
347 return tty->index + (tty->driver == rio_driver) ? 0 : 256;
348}
349
350
351int rio_ismodem(struct tty_struct *tty)
352{
353 return 1;
354}
355
356
357void rio_udelay (int usecs)
358{
359 udelay (usecs);
360}
361
362static int rio_set_real_termios (void *ptr)
363{
364 int rv, modem;
365 struct tty_struct *tty;
366 func_enter();
367
368 tty = ((struct Port *)ptr)->gs.tty;
369
370 modem = rio_ismodem(tty);
371
372 rv = RIOParam( (struct Port *) ptr, CONFIG, modem, 1);
373
374 func_exit ();
375
376 return rv;
377}
378
379
380static void rio_reset_interrupt (struct Host *HostP)
381{
382 func_enter();
383
384 switch( HostP->Type ) {
385 case RIO_AT:
386 case RIO_MCA:
387 case RIO_PCI:
388 WBYTE(HostP->ResetInt , 0xff);
389 }
390
391 func_exit();
392}
393
394
395static irqreturn_t rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
396{
397 struct Host *HostP;
398 func_enter ();
399
400 HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */
401 rio_dprintk (RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n",
402 irq, HostP->Ivec);
403
404 /* AAargh! The order in which to do these things is essential and
405 not trivial.
406
407 - Rate limit goes before "recursive". Otherwise a series of
408 recursive calls will hang the machine in the interrupt routine.
409
410 - hardware twiddling goes before "recursive". Otherwise when we
411 poll the card, and a recursive interrupt happens, we won't
412 ack the card, so it might keep on interrupting us. (especially
413 level sensitive interrupt systems like PCI).
414
415 - Rate limit goes before hardware twiddling. Otherwise we won't
416 catch a card that has gone bonkers.
417
418 - The "initialized" test goes after the hardware twiddling. Otherwise
419 the card will stick us in the interrupt routine again.
420
421 - The initialized test goes before recursive.
422 */
423
424
425
426#ifdef IRQ_RATE_LIMIT
427 /* Aaargh! I'm ashamed. This costs more lines-of-code than the
428 actual interrupt routine!. (Well, used to when I wrote that comment) */
429 {
430 static int lastjif;
431 static int nintr=0;
432
433 if (lastjif == jiffies) {
434 if (++nintr > IRQ_RATE_LIMIT) {
435 free_irq (HostP->Ivec, ptr);
436 printk (KERN_ERR "rio: Too many interrupts. Turning off interrupt %d.\n",
437 HostP->Ivec);
438 }
439 } else {
440 lastjif = jiffies;
441 nintr = 0;
442 }
443 }
444#endif
445 rio_dprintk (RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n");
446 if (HostP->Ivec == irq) {
447 /* Tell the card we've noticed the interrupt. */
448 rio_reset_interrupt (HostP);
449 }
450
451 if ((HostP->Flags & RUN_STATE) != RC_RUNNING)
452 return IRQ_HANDLED;
453
454 if (test_and_set_bit (RIO_BOARD_INTR_LOCK, &HostP->locks)) {
455 printk (KERN_ERR "Recursive interrupt! (host %d/irq%d)\n",
456 (int) ptr, HostP->Ivec);
457 return IRQ_HANDLED;
458 }
459
460 RIOServiceHost(p, HostP, irq);
461
462 rio_dprintk ( RIO_DEBUG_IFLOW, "riointr() doing host %d type %d\n",
463 (int) ptr, HostP->Type);
464
465 clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks);
466 rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n",
467 irq, HostP->Ivec);
468 func_exit ();
469 return IRQ_HANDLED;
470}
471
472
473static void rio_pollfunc (unsigned long data)
474{
475 func_enter ();
476
477 rio_interrupt (0, &p->RIOHosts[data], NULL);
478 p->RIOHosts[data].timer.expires = jiffies + rio_poll;
479 add_timer (&p->RIOHosts[data].timer);
480
481 func_exit ();
482}
483
484
485/* ********************************************************************** *
486 * Here are the routines that actually *
487 * interface with the generic_serial driver *
488 * ********************************************************************** */
489
490/* Ehhm. I don't know how to fiddle with interrupts on the Specialix
491 cards. .... Hmm. Ok I figured it out. You don't. -- REW */
492
493static void rio_disable_tx_interrupts (void * ptr)
494{
495 func_enter();
496
497 /* port->gs.flags &= ~GS_TX_INTEN; */
498
499 func_exit();
500}
501
502
503static void rio_enable_tx_interrupts (void * ptr)
504{
505 struct Port *PortP = ptr;
506 /* int hn; */
507
508 func_enter();
509
510 /* hn = PortP->HostP - p->RIOHosts;
511
512 rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn);
513 rio_interrupt (-1,(void *) hn, NULL); */
514
515 RIOTxEnable((char *) PortP);
516
517 /*
518 * In general we cannot count on "tx empty" interrupts, although
519 * the interrupt routine seems to be able to tell the difference.
520 */
521 PortP->gs.flags &= ~GS_TX_INTEN;
522
523 func_exit();
524}
525
526
527static void rio_disable_rx_interrupts (void * ptr)
528{
529 func_enter();
530 func_exit();
531}
532
533static void rio_enable_rx_interrupts (void * ptr)
534{
535 /* struct rio_port *port = ptr; */
536 func_enter();
537 func_exit();
538}
539
540
541/* Jeez. Isn't this simple? */
542static int rio_get_CD (void * ptr)
543{
544 struct Port *PortP = ptr;
545 int rv;
546
547 func_enter();
548 rv = (PortP->ModemState & MSVR1_CD) != 0;
549
550 rio_dprintk (RIO_DEBUG_INIT, "Getting CD status: %d\n", rv);
551
552 func_exit();
553 return rv;
554}
555
556
557/* Jeez. Isn't this simple? Actually, we can sync with the actual port
558 by just pushing stuff into the queue going to the port... */
559static int rio_chars_in_buffer (void * ptr)
560{
561 func_enter();
562
563 func_exit();
564 return 0;
565}
566
567
568/* Nothing special here... */
569static void rio_shutdown_port (void * ptr)
570{
571 struct Port *PortP;
572
573 func_enter();
574
575 PortP = (struct Port *)ptr;
576 PortP->gs.tty = NULL;
577#if 0
578 port->gs.flags &= ~ GS_ACTIVE;
579 if (!port->gs.tty) {
580 rio_dprintk (RIO_DBUG_TTY, "No tty.\n");
581 return;
582 }
583 if (!port->gs.tty->termios) {
584 rio_dprintk (RIO_DEBUG_TTY, "No termios.\n");
585 return;
586 }
587 if (port->gs.tty->termios->c_cflag & HUPCL) {
588 rio_setsignals (port, 0, 0);
589 }
590#endif
591
592 func_exit();
593}
594
595
596/* I haven't the foggiest why the decrement use count has to happen
597 here. The whole linux serial drivers stuff needs to be redesigned.
598 My guess is that this is a hack to minimize the impact of a bug
599 elsewhere. Thinking about it some more. (try it sometime) Try
600 running minicom on a serial port that is driven by a modularized
601 driver. Have the modem hangup. Then remove the driver module. Then
602 exit minicom. I expect an "oops". -- REW */
603static void rio_hungup (void *ptr)
604{
605 struct Port *PortP;
606
607 func_enter();
608
609 PortP = (struct Port *)ptr;
610 PortP->gs.tty = NULL;
611
612 func_exit ();
613}
614
615
616/* The standard serial_close would become shorter if you'd wrap it like
617 this.
618 rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;}
619 */
620static void rio_close (void *ptr)
621{
622 struct Port *PortP;
623
624 func_enter ();
625
626 PortP = (struct Port *)ptr;
627
628 riotclose (ptr);
629
630 if(PortP->gs.count) {
631 printk (KERN_ERR "WARNING port count:%d\n", PortP->gs.count);
632 PortP->gs.count = 0;
633 }
634
635 PortP->gs.tty = NULL;
636 func_exit ();
637}
638
639
640
641static int rio_fw_ioctl (struct inode *inode, struct file *filp,
642 unsigned int cmd, unsigned long arg)
643{
644 int rc = 0;
645 func_enter();
646
647 /* The "dev" argument isn't used. */
648 rc = riocontrol (p, 0, cmd, (void *)arg, capable(CAP_SYS_ADMIN));
649
650 func_exit ();
651 return rc;
652}
653
654extern int RIOShortCommand(struct rio_info *p, struct Port *PortP,
655 int command, int len, int arg);
656
657static int rio_ioctl (struct tty_struct * tty, struct file * filp,
658 unsigned int cmd, unsigned long arg)
659{
660 int rc;
661 struct Port *PortP;
662 int ival;
663
664 func_enter();
665
666 PortP = (struct Port *)tty->driver_data;
667
668 rc = 0;
669 switch (cmd) {
670#if 0
671 case TIOCGSOFTCAR:
672 rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
673 (unsigned int *) arg);
674 break;
675#endif
676 case TIOCSSOFTCAR:
677 if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
678 tty->termios->c_cflag =
679 (tty->termios->c_cflag & ~CLOCAL) |
680 (ival ? CLOCAL : 0);
681 }
682 break;
683 case TIOCGSERIAL:
684 rc = -EFAULT;
685 if (access_ok(VERIFY_WRITE, (void *) arg,
686 sizeof(struct serial_struct)))
687 rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg);
688 break;
689 case TCSBRK:
690 if ( PortP->State & RIO_DELETED ) {
691 rio_dprintk (RIO_DEBUG_TTY, "BREAK on deleted RTA\n");
692 rc = -EIO;
693 } else {
694 if (RIOShortCommand(p, PortP, SBREAK, 2, 250) == RIO_FAIL) {
695 rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
696 rc = -EIO;
697 }
698 }
699 break;
700 case TCSBRKP:
701 if ( PortP->State & RIO_DELETED ) {
702 rio_dprintk (RIO_DEBUG_TTY, "BREAK on deleted RTA\n");
703 rc = -EIO;
704 } else {
705 int l;
706 l = arg?arg*100:250;
707 if (l > 255) l = 255;
708 if (RIOShortCommand(p, PortP, SBREAK, 2, arg?arg*100:250) == RIO_FAIL) {
709 rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
710 rc = -EIO;
711 }
712 }
713 break;
714 case TIOCSSERIAL:
715 rc = -EFAULT;
716 if (access_ok(VERIFY_READ, (void *) arg,
717 sizeof(struct serial_struct)))
718 rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg);
719 break;
720#if 0
721 /*
722 * note: these IOCTLs no longer reach here. Use
723 * tiocmset/tiocmget driver methods instead. The
724 * #if 0 disablement predates this comment.
725 */
726 case TIOCMGET:
727 rc = -EFAULT;
728 if (access_ok(VERIFY_WRITE, (void *) arg,
729 sizeof(unsigned int))) {
730 rc = 0;
731 ival = rio_getsignals(port);
732 put_user(ival, (unsigned int *) arg);
733 }
734 break;
735 case TIOCMBIS:
736 if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
737 rio_setsignals(port, ((ival & TIOCM_DTR) ? 1 : -1),
738 ((ival & TIOCM_RTS) ? 1 : -1));
739 }
740 break;
741 case TIOCMBIC:
742 if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
743 rio_setsignals(port, ((ival & TIOCM_DTR) ? 0 : -1),
744 ((ival & TIOCM_RTS) ? 0 : -1));
745 }
746 break;
747 case TIOCMSET:
748 if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
749 rio_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0),
750 ((ival & TIOCM_RTS) ? 1 : 0));
751 }
752 break;
753#endif
754 default:
755 rc = -ENOIOCTLCMD;
756 break;
757 }
758 func_exit();
759 return rc;
760}
761
762
763/* The throttle/unthrottle scheme for the Specialix card is different
764 * from other drivers and deserves some explanation.
765 * The Specialix hardware takes care of XON/XOFF
766 * and CTS/RTS flow control itself. This means that all we have to
767 * do when signalled by the upper tty layer to throttle/unthrottle is
768 * to make a note of it here. When we come to read characters from the
769 * rx buffers on the card (rio_receive_chars()) we look to see if the
770 * upper layer can accept more (as noted here in rio_rx_throt[]).
771 * If it can't we simply don't remove chars from the cards buffer.
772 * When the tty layer can accept chars, we again note that here and when
773 * rio_receive_chars() is called it will remove them from the cards buffer.
774 * The card will notice that a ports buffer has drained below some low
775 * water mark and will unflow control the line itself, using whatever
776 * flow control scheme is in use for that port. -- Simon Allen
777 */
778
779static void rio_throttle (struct tty_struct * tty)
780{
781 struct Port *port = (struct Port *)tty->driver_data;
782
783 func_enter();
784 /* If the port is using any type of input flow
785 * control then throttle the port.
786 */
787
788 if((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty)) ) {
789 port->State |= RIO_THROTTLE_RX;
790 }
791
792 func_exit();
793}
794
795
796static void rio_unthrottle (struct tty_struct * tty)
797{
798 struct Port *port = (struct Port *)tty->driver_data;
799
800 func_enter();
801 /* Always unthrottle even if flow control is not enabled on
802 * this port in case we disabled flow control while the port
803 * was throttled
804 */
805
806 port->State &= ~RIO_THROTTLE_RX;
807
808 func_exit();
809 return;
810}
811
812
813
814
815
816/* ********************************************************************** *
817 * Here are the initialization routines. *
818 * ********************************************************************** */
819
820
821static struct vpd_prom *get_VPD_PROM (struct Host *hp)
822{
823 static struct vpd_prom vpdp;
824 char *p;
825 int i;
826
827 func_enter();
828 rio_dprintk (RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n",
829 hp->Caddr + RIO_VPD_ROM);
830
831 p = (char *) &vpdp;
832 for (i=0;i< sizeof (struct vpd_prom);i++)
833 *p++ = readb (hp->Caddr+RIO_VPD_ROM + i*2);
834 /* read_rio_byte (hp, RIO_VPD_ROM + i*2); */
835
836 /* Terminate the identifier string.
837 *** requires one extra byte in struct vpd_prom *** */
838 *p++=0;
839
840 if (rio_debug & RIO_DEBUG_PROBE)
841 my_hd ((char *)&vpdp, 0x20);
842
843 func_exit();
844
845 return &vpdp;
846}
847
848static struct tty_operations rio_ops = {
849 .open = riotopen,
850 .close = gs_close,
851 .write = gs_write,
852 .put_char = gs_put_char,
853 .flush_chars = gs_flush_chars,
854 .write_room = gs_write_room,
855 .chars_in_buffer = gs_chars_in_buffer,
856 .flush_buffer = gs_flush_buffer,
857 .ioctl = rio_ioctl,
858 .throttle = rio_throttle,
859 .unthrottle = rio_unthrottle,
860 .set_termios = gs_set_termios,
861 .stop = gs_stop,
862 .start = gs_start,
863 .hangup = gs_hangup,
864};
865
866static int rio_init_drivers(void)
867{
868 int error = -ENOMEM;
869
870 rio_driver = alloc_tty_driver(256);
871 if (!rio_driver)
872 goto out;
873 rio_driver2 = alloc_tty_driver(256);
874 if (!rio_driver2)
875 goto out1;
876
877 func_enter();
878
879 rio_driver->owner = THIS_MODULE;
880 rio_driver->driver_name = "specialix_rio";
881 rio_driver->name = "ttySR";
882 rio_driver->major = RIO_NORMAL_MAJOR0;
883 rio_driver->type = TTY_DRIVER_TYPE_SERIAL;
884 rio_driver->subtype = SERIAL_TYPE_NORMAL;
885 rio_driver->init_termios = tty_std_termios;
886 rio_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
887 rio_driver->flags = TTY_DRIVER_REAL_RAW;
888 tty_set_operations(rio_driver, &rio_ops);
889
890 rio_driver2->owner = THIS_MODULE;
891 rio_driver2->driver_name = "specialix_rio";
892 rio_driver2->name = "ttySR";
893 rio_driver2->major = RIO_NORMAL_MAJOR1;
894 rio_driver2->type = TTY_DRIVER_TYPE_SERIAL;
895 rio_driver2->subtype = SERIAL_TYPE_NORMAL;
896 rio_driver2->init_termios = tty_std_termios;
897 rio_driver2->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
898 rio_driver2->flags = TTY_DRIVER_REAL_RAW;
899 tty_set_operations(rio_driver2, &rio_ops);
900
901 rio_dprintk (RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios);
902
903 if ((error = tty_register_driver(rio_driver)))
904 goto out2;
905 if ((error = tty_register_driver(rio_driver2)))
906 goto out3;
907 func_exit();
908 return 0;
909out3:
910 tty_unregister_driver(rio_driver);
911out2:
912 put_tty_driver(rio_driver2);
913out1:
914 put_tty_driver(rio_driver);
915out:
916 printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n",
917 error);
918 return 1;
919}
920
921
922static void * ckmalloc (int size)
923{
924 void *p;
925
926 p = kmalloc(size, GFP_KERNEL);
927 if (p)
928 memset(p, 0, size);
929 return p;
930}
931
932
933
934static int rio_init_datastructures (void)
935{
936 int i;
937 struct Port *port;
938 func_enter();
939
940 /* Many drivers statically allocate the maximum number of ports
941 There is no reason not to allocate them dynamically. Is there? -- REW */
942 /* However, the RIO driver allows users to configure their first
943 RTA as the ports numbered 504-511. We therefore need to allocate
944 the whole range. :-( -- REW */
945
946#define RI_SZ sizeof(struct rio_info)
947#define HOST_SZ sizeof(struct Host)
948#define PORT_SZ sizeof(struct Port *)
949#define TMIO_SZ sizeof(struct termios *)
950 rio_dprintk (RIO_DEBUG_INIT, "getting : %d %d %d %d %d bytes\n",
951 RI_SZ,
952 RIO_HOSTS * HOST_SZ,
953 RIO_PORTS * PORT_SZ,
954 RIO_PORTS * TMIO_SZ,
955 RIO_PORTS * TMIO_SZ);
956
957 if (!(p = ckmalloc ( RI_SZ))) goto free0;
958 if (!(p->RIOHosts = ckmalloc (RIO_HOSTS * HOST_SZ))) goto free1;
959 if (!(p->RIOPortp = ckmalloc (RIO_PORTS * PORT_SZ))) goto free2;
960 p->RIOConf = RIOConf;
961 rio_dprintk (RIO_DEBUG_INIT, "Got : %p %p %p\n",
962 p, p->RIOHosts, p->RIOPortp);
963
964#if 1
965 for (i = 0; i < RIO_PORTS; i++) {
966 port = p->RIOPortp[i] = ckmalloc (sizeof (struct Port));
967 if (!port) {
968 goto free6;
969 }
970 rio_dprintk (RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped);
971 port->PortNum = i;
972 port->gs.magic = RIO_MAGIC;
973 port->gs.close_delay = HZ/2;
974 port->gs.closing_wait = 30 * HZ;
975 port->gs.rd = &rio_real_driver;
976 spin_lock_init(&port->portSem);
977 /*
978 * Initializing wait queue
979 */
980 init_waitqueue_head(&port->gs.open_wait);
981 init_waitqueue_head(&port->gs.close_wait);
982 }
983#else
984 /* We could postpone initializing them to when they are configured. */
985#endif
986
987
988
989 if (rio_debug & RIO_DEBUG_INIT) {
990 my_hd (&rio_real_driver, sizeof (rio_real_driver));
991 }
992
993
994 func_exit();
995 return 0;
996
997 free6:for (i--;i>=0;i--)
998 kfree (p->RIOPortp[i]);
999/*free5:
1000 free4:
1001 free3:*/kfree (p->RIOPortp);
1002 free2:kfree (p->RIOHosts);
1003 free1:
1004 rio_dprintk (RIO_DEBUG_INIT, "Not enough memory! %p %p %p\n",
1005 p, p->RIOHosts, p->RIOPortp);
1006 kfree(p);
1007 free0:
1008 return -ENOMEM;
1009}
1010
1011static void __exit rio_release_drivers(void)
1012{
1013 func_enter();
1014 tty_unregister_driver(rio_driver2);
1015 tty_unregister_driver(rio_driver);
1016 put_tty_driver(rio_driver2);
1017 put_tty_driver(rio_driver);
1018 func_exit();
1019}
1020
1021
1022#ifdef CONFIG_PCI
1023 /* This was written for SX, but applies to RIO too...
1024 (including bugs....)
1025
1026 There is another bit besides Bit 17. Turning that bit off
1027 (on boards shipped with the fix in the eeprom) results in a
1028 hang on the next access to the card.
1029 */
1030
1031 /********************************************************
1032 * Setting bit 17 in the CNTRL register of the PLX 9050 *
1033 * chip forces a retry on writes while a read is pending.*
1034 * This is to prevent the card locking up on Intel Xeon *
1035 * multiprocessor systems with the NX chipset. -- NV *
1036 ********************************************************/
1037
1038/* Newer cards are produced with this bit set from the configuration
1039 EEprom. As the bit is read/write for the CPU, we can fix it here,
1040 if we detect that it isn't set correctly. -- REW */
1041
1042static void fix_rio_pci (struct pci_dev *pdev)
1043{
1044 unsigned int hwbase;
1045 unsigned long rebase;
1046 unsigned int t;
1047
1048#define CNTRL_REG_OFFSET 0x50
1049#define CNTRL_REG_GOODVALUE 0x18260000
1050
1051 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
1052 hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
1053 rebase = (ulong) ioremap(hwbase, 0x80);
1054 t = readl (rebase + CNTRL_REG_OFFSET);
1055 if (t != CNTRL_REG_GOODVALUE) {
1056 printk (KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n",
1057 t, CNTRL_REG_GOODVALUE);
1058 writel (CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET);
1059 }
1060 iounmap((char*) rebase);
1061}
1062#endif
1063
1064
1065static int __init rio_init(void)
1066{
1067 int found = 0;
1068 int i;
1069 struct Host *hp;
1070 int retval;
1071 struct vpd_prom *vpdp;
1072 int okboard;
1073
1074#ifdef CONFIG_PCI
1075 struct pci_dev *pdev = NULL;
1076 unsigned int tint;
1077 unsigned short tshort;
1078#endif
1079
1080 func_enter();
1081 rio_dprintk (RIO_DEBUG_INIT, "Initing rio module... (rio_debug=%d)\n",
1082 rio_debug);
1083
1084 if (abs ((long) (&rio_debug) - rio_debug) < 0x10000) {
1085 printk (KERN_WARNING "rio: rio_debug is an address, instead of a value. "
1086 "Assuming -1. Was %x/%p.\n", rio_debug, &rio_debug);
1087 rio_debug=-1;
1088 }
1089
1090 if (misc_register(&rio_fw_device) < 0) {
1091 printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n");
1092 return -EIO;
1093 }
1094
1095 retval = rio_init_datastructures ();
1096 if (retval < 0) {
1097 misc_deregister(&rio_fw_device);
1098 return retval;
1099 }
1100
1101#ifdef CONFIG_PCI
1102 /* First look for the JET devices: */
1103 while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
1104 PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
1105 pdev))) {
1106 if (pci_enable_device(pdev)) continue;
1107
1108 /* Specialix has a whole bunch of cards with
1109 0x2000 as the device ID. They say its because
1110 the standard requires it. Stupid standard. */
1111 /* It seems that reading a word doesn't work reliably on 2.0.
1112 Also, reading a non-aligned dword doesn't work. So we read the
1113 whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID)
1114 ourselves */
1115 /* I don't know why the define doesn't work, constant 0x2c does --REW */
1116 pci_read_config_dword (pdev, 0x2c, &tint);
1117 tshort = (tint >> 16) & 0xffff;
1118 rio_dprintk (RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
1119 if (tshort != 0x0100) {
1120 rio_dprintk (RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n",
1121 tshort);
1122 continue;
1123 }
1124 rio_dprintk (RIO_DEBUG_PROBE, "cp1\n");
1125
1126 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, &tint);
1127
1128 hp = &p->RIOHosts[p->RIONumHosts];
1129 hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK;
1130 hp->Ivec = pdev->irq;
1131 if (((1 << hp->Ivec) & rio_irqmask) == 0)
1132 hp->Ivec = 0;
1133 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
1134 hp->CardP = (struct DpRam *) hp->Caddr;
1135 hp->Type = RIO_PCI;
1136 hp->Copy = rio_pcicopy;
1137 hp->Mode = RIO_PCI_BOOT_FROM_RAM;
1138 spin_lock_init(&hp->HostLock);
1139 rio_reset_interrupt (hp);
1140 rio_start_card_running (hp);
1141
1142 rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
1143 (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
1144 p->RIOHosts[p->RIONumHosts].Caddr);
1145 if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
1146 p->RIOHosts[p->RIONumHosts].Caddr,
1147 RIO_PCI, 0 ) == RIO_SUCCESS) {
1148 rio_dprintk (RIO_DEBUG_INIT, "Done RIOBoardTest\n");
1149 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
1150 p->RIOHosts[p->RIONumHosts].UniqueNum =
1151 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
1152 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
1153 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
1154 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
1155 rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
1156 p->RIOHosts[p->RIONumHosts].UniqueNum);
1157
1158 fix_rio_pci (pdev);
1159 p->RIOLastPCISearch = RIO_SUCCESS;
1160 p->RIONumHosts++;
1161 found++;
1162 } else {
1163 iounmap((char*) (p->RIOHosts[p->RIONumHosts].Caddr));
1164 }
1165 }
1166
1167 /* Then look for the older PCI card.... : */
1168
1169 /* These older PCI cards have problems (only byte-mode access is
1170 supported), which makes them a bit awkward to support.
1171 They also have problems sharing interrupts. Be careful.
1172 (The driver now refuses to share interrupts for these
1173 cards. This should be sufficient).
1174 */
1175
1176 /* Then look for the older RIO/PCI devices: */
1177 while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
1178 PCI_DEVICE_ID_SPECIALIX_RIO,
1179 pdev))) {
1180 if (pci_enable_device(pdev)) continue;
1181
1182#ifdef CONFIG_RIO_OLDPCI
1183 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &tint);
1184
1185 hp = &p->RIOHosts[p->RIONumHosts];
1186 hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK;
1187 hp->Ivec = pdev->irq;
1188 if (((1 << hp->Ivec) & rio_irqmask) == 0)
1189 hp->Ivec = 0;
1190 hp->Ivec |= 0x8000; /* Mark as non-sharable */
1191 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
1192 hp->CardP = (struct DpRam *) hp->Caddr;
1193 hp->Type = RIO_PCI;
1194 hp->Copy = rio_pcicopy;
1195 hp->Mode = RIO_PCI_BOOT_FROM_RAM;
1196 spin_lock_init(&hp->HostLock);
1197
1198 rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec);
1199 rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode);
1200
1201 rio_reset_interrupt (hp);
1202 rio_start_card_running (hp);
1203 rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
1204 (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
1205 p->RIOHosts[p->RIONumHosts].Caddr);
1206 if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
1207 p->RIOHosts[p->RIONumHosts].Caddr,
1208 RIO_PCI, 0 ) == RIO_SUCCESS) {
1209 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
1210 p->RIOHosts[p->RIONumHosts].UniqueNum =
1211 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
1212 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
1213 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
1214 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
1215 rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
1216 p->RIOHosts[p->RIONumHosts].UniqueNum);
1217
1218 p->RIOLastPCISearch = RIO_SUCCESS;
1219 p->RIONumHosts++;
1220 found++;
1221 } else {
1222 iounmap((char*) (p->RIOHosts[p->RIONumHosts].Caddr));
1223 }
1224#else
1225 printk (KERN_ERR "Found an older RIO PCI card, but the driver is not "
1226 "compiled to support it.\n");
1227#endif
1228 }
1229#endif /* PCI */
1230
1231 /* Now probe for ISA cards... */
1232 for (i=0;i<NR_RIO_ADDRS;i++) {
1233 hp = &p->RIOHosts[p->RIONumHosts];
1234 hp->PaddrP = rio_probe_addrs[i];
1235 /* There was something about the IRQs of these cards. 'Forget what.--REW */
1236 hp->Ivec = 0;
1237 hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
1238 hp->CardP = (struct DpRam *) hp->Caddr;
1239 hp->Type = RIO_AT;
1240 hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL
1241 * -- YES! this is now a normal copy. Only the
1242 * old PCI card uses the special PCI copy.
1243 * Moreover, the ISA card will work with the
1244 * special PCI copy anyway. -- REW */
1245 hp->Mode = 0;
1246 spin_lock_init(&hp->HostLock);
1247
1248 vpdp = get_VPD_PROM (hp);
1249 rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n");
1250 okboard = 0;
1251 if ((strncmp (vpdp->identifier, RIO_ISA_IDENT, 16) == 0) ||
1252 (strncmp (vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) ||
1253 (strncmp (vpdp->identifier, RIO_ISA3_IDENT, 16) == 0)) {
1254 /* Board is present... */
1255 if (RIOBoardTest (hp->PaddrP,
1256 hp->Caddr, RIO_AT, 0) == RIO_SUCCESS) {
1257 /* ... and feeling fine!!!! */
1258 rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
1259 p->RIOHosts[p->RIONumHosts].UniqueNum);
1260 if (RIOAssignAT(p, hp->PaddrP, hp->Caddr, 0)) {
1261 rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, host%d uniqid = %x.\n",
1262 p->RIONumHosts,
1263 p->RIOHosts[p->RIONumHosts-1].UniqueNum);
1264 okboard++;
1265 found++;
1266 }
1267 }
1268
1269 if (!okboard)
1270 iounmap ((char*) (hp->Caddr));
1271 }
1272 }
1273
1274
1275 for (i=0;i<p->RIONumHosts;i++) {
1276 hp = &p->RIOHosts[i];
1277 if (hp->Ivec) {
1278 int mode = SA_SHIRQ;
1279 if (hp->Ivec & 0x8000) {mode = 0; hp->Ivec &= 0x7fff;}
1280 rio_dprintk (RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp,hp->Ivec, hp->Mode);
1281 retval = request_irq (hp->Ivec, rio_interrupt, mode, "rio", hp);
1282 rio_dprintk (RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval);
1283 if (retval) {
1284 printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
1285 hp->Ivec = 0;
1286 }
1287 rio_dprintk (RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec);
1288 if (hp->Ivec != 0){
1289 rio_dprintk (RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n");
1290 hp->Mode |= RIO_PCI_INT_ENABLE;
1291 } else
1292 hp->Mode &= !RIO_PCI_INT_ENABLE;
1293 rio_dprintk (RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode);
1294 rio_start_card_running (hp);
1295 }
1296 /* Init the timer "always" to make sure that it can safely be
1297 deleted when we unload... */
1298
1299 init_timer (&hp->timer);
1300 if (!hp->Ivec) {
1301 rio_dprintk (RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n",
1302 rio_poll);
1303 hp->timer.data = i;
1304 hp->timer.function = rio_pollfunc;
1305 hp->timer.expires = jiffies + rio_poll;
1306 add_timer (&hp->timer);
1307 }
1308 }
1309
1310 if (found) {
1311 rio_dprintk (RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found);
1312 rio_init_drivers ();
1313 } else {
1314 /* deregister the misc device we created earlier */
1315 misc_deregister(&rio_fw_device);
1316 }
1317
1318 func_exit();
1319 return found?0:-EIO;
1320}
1321
1322
1323static void __exit rio_exit (void)
1324{
1325 int i;
1326 struct Host *hp;
1327
1328 func_enter();
1329
1330 for (i=0,hp=p->RIOHosts;i<p->RIONumHosts;i++, hp++) {
1331 RIOHostReset (hp->Type, hp->CardP, hp->Slot);
1332 if (hp->Ivec) {
1333 free_irq (hp->Ivec, hp);
1334 rio_dprintk (RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec);
1335 }
1336 /* It is safe/allowed to del_timer a non-active timer */
1337 del_timer (&hp->timer);
1338 }
1339
1340 if (misc_deregister(&rio_fw_device) < 0) {
1341 printk (KERN_INFO "rio: couldn't deregister control-device\n");
1342 }
1343
1344
1345 rio_dprintk (RIO_DEBUG_CLEANUP, "Cleaning up drivers\n");
1346
1347 rio_release_drivers ();
1348
1349 /* Release dynamically allocated memory */
1350 kfree (p->RIOPortp);
1351 kfree (p->RIOHosts);
1352 kfree (p);
1353
1354 func_exit();
1355}
1356
1357module_init(rio_init);
1358module_exit(rio_exit);
1359
1360/*
1361 * Anybody who knows why this doesn't work for me, please tell me -- REW.
1362 * Snatched from scsi.c (fixed one spelling error):
1363 * Overrides for Emacs so that we follow Linus' tabbing style.
1364 * Emacs will notice this stuff at the end of the file and automatically
1365 * adjust the settings for this buffer only. This must remain at the end
1366 * of the file.
1367 * ---------------------------------------------------------------------------
1368 * Local Variables:
1369 * c-indent-level: 4
1370 * c-brace-imaginary-offset: 0
1371 * c-brace-offset: -4
1372 * c-argdecl-indent: 4
1373 * c-label-offset: -4
1374 * c-continued-statement-offset: 4
1375 * c-continued-brace-offset: 0
1376 * indent-tabs-mode: nil
1377 * tab-width: 8
1378 * End:
1379 */
1380
diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h
new file mode 100644
index 000000000000..1fba19d5b66a
--- /dev/null
+++ b/drivers/char/rio/rio_linux.h
@@ -0,0 +1,187 @@
1
2/*
3 * rio_linux.h
4 *
5 * Copyright (C) 1998,1999,2000 R.E.Wolff@BitWizard.nl
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * RIO serial driver.
22 *
23 * Version 1.0 -- July, 1999.
24 *
25 */
26#include <linux/config.h>
27
28#define RIO_NBOARDS 4
29#define RIO_PORTSPERBOARD 128
30#define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD)
31
32#define MODEM_SUPPORT
33
34#ifdef __KERNEL__
35
36#define RIO_MAGIC 0x12345678
37
38
39struct vpd_prom {
40 unsigned short id;
41 char hwrev;
42 char hwass;
43 int uniqid;
44 char myear;
45 char mweek;
46 char hw_feature[5];
47 char oem_id;
48 char identifier[16];
49};
50
51
52#define RIO_DEBUG_ALL 0xffffffff
53
54#define O_OTHER(tty) \
55 ((O_OLCUC(tty)) ||\
56 (O_ONLCR(tty)) ||\
57 (O_OCRNL(tty)) ||\
58 (O_ONOCR(tty)) ||\
59 (O_ONLRET(tty)) ||\
60 (O_OFILL(tty)) ||\
61 (O_OFDEL(tty)) ||\
62 (O_NLDLY(tty)) ||\
63 (O_CRDLY(tty)) ||\
64 (O_TABDLY(tty)) ||\
65 (O_BSDLY(tty)) ||\
66 (O_VTDLY(tty)) ||\
67 (O_FFDLY(tty)))
68
69/* Same for input. */
70#define I_OTHER(tty) \
71 ((I_INLCR(tty)) ||\
72 (I_IGNCR(tty)) ||\
73 (I_ICRNL(tty)) ||\
74 (I_IUCLC(tty)) ||\
75 (L_ISIG(tty)))
76
77
78#endif /* __KERNEL__ */
79
80
81#define RIO_BOARD_INTR_LOCK 1
82
83
84#ifndef RIOCTL_MISC_MINOR
85/* Allow others to gather this into "major.h" or something like that */
86#define RIOCTL_MISC_MINOR 169
87#endif
88
89
90/* Allow us to debug "in the field" without requiring clients to
91 recompile.... */
92#if 1
93#define rio_spin_lock_irqsave(sem, flags) do { \
94 rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \
95 sem, __FILE__, __LINE__);\
96 spin_lock_irqsave(sem, flags);\
97 } while (0)
98
99#define rio_spin_unlock_irqrestore(sem, flags) do { \
100 rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\
101 sem, __FILE__, __LINE__);\
102 spin_unlock_irqrestore(sem, flags);\
103 } while (0)
104
105#define rio_spin_lock(sem) do { \
106 rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\
107 sem, __FILE__, __LINE__);\
108 spin_lock(sem);\
109 } while (0)
110
111#define rio_spin_unlock(sem) do { \
112 rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\
113 sem, __FILE__, __LINE__);\
114 spin_unlock(sem);\
115 } while (0)
116#else
117#define rio_spin_lock_irqsave(sem, flags) \
118 spin_lock_irqsave(sem, flags)
119
120#define rio_spin_unlock_irqrestore(sem, flags) \
121 spin_unlock_irqrestore(sem, flags)
122
123#define rio_spin_lock(sem) \
124 spin_lock(sem)
125
126#define rio_spin_unlock(sem) \
127 spin_unlock(sem)
128
129#endif
130
131
132
133#ifdef CONFIG_RIO_OLDPCI
134static inline void *rio_memcpy_toio (void *dummy, void *dest, void *source, int n)
135{
136 char *dst = dest;
137 char *src = source;
138
139 while (n--) {
140 writeb (*src++, dst++);
141 (void) readb (dummy);
142 }
143
144 return dest;
145}
146
147
148static inline void *rio_memcpy_fromio (void *dest, void *source, int n)
149{
150 char *dst = dest;
151 char *src = source;
152
153 while (n--)
154 *dst++ = readb (src++);
155
156 return dest;
157}
158
159#else
160#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n)
161#define rio_memcpy_fromio memcpy_fromio
162#endif
163
164#define DEBUG 1
165
166
167/*
168 This driver can spew a whole lot of debugging output at you. If you
169 need maximum performance, you should disable the DEBUG define. To
170 aid in debugging in the field, I'm leaving the compile-time debug
171 features enabled, and disable them "runtime". That allows me to
172 instruct people with problems to enable debugging without requiring
173 them to recompile...
174*/
175
176#ifdef DEBUG
177#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0)
178#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __FUNCTION__)
179#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __FUNCTION__)
180#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__FUNCTION__, port->line)
181#else
182#define rio_dprintk(f, str...) /* nothing */
183#define func_enter()
184#define func_exit()
185#define func_enter2()
186#endif
187
diff --git a/drivers/char/rio/rioboard.h b/drivers/char/rio/rioboard.h
new file mode 100644
index 000000000000..cc6ac6a98f65
--- /dev/null
+++ b/drivers/char/rio/rioboard.h
@@ -0,0 +1,281 @@
1/************************************************************************/
2/* */
3/* Title : RIO Host Card Hardware Definitions */
4/* */
5/* Author : N.P.Vassallo */
6/* */
7/* Creation : 26th April 1999 */
8/* */
9/* Version : 1.0.0 */
10/* */
11/* Copyright : (c) Specialix International Ltd. 1999 *
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/* Description : Prototypes, structures and definitions */
28/* describing the RIO board hardware */
29/* */
30/************************************************************************/
31
32/* History...
33
341.0.0 26/04/99 NPV Creation.
35
36*/
37
38#ifndef _rioboard_h /* If RIOBOARD.H not already defined */
39#define _rioboard_h 1
40
41/*****************************************************************************
42*********************** ***********************
43*********************** Hardware Control Registers ***********************
44*********************** ***********************
45*****************************************************************************/
46
47/* Hardware Registers... */
48
49#define RIO_REG_BASE 0x7C00 /* Base of control registers */
50
51#define RIO_CONFIG RIO_REG_BASE + 0x0000 /* WRITE: Configuration Register */
52#define RIO_INTSET RIO_REG_BASE + 0x0080 /* WRITE: Interrupt Set */
53#define RIO_RESET RIO_REG_BASE + 0x0100 /* WRITE: Host Reset */
54#define RIO_INTRESET RIO_REG_BASE + 0x0180 /* WRITE: Interrupt Reset */
55
56#define RIO_VPD_ROM RIO_REG_BASE + 0x0000 /* READ: Vital Product Data ROM */
57#define RIO_INTSTAT RIO_REG_BASE + 0x0080 /* READ: Interrupt Status (Jet boards only) */
58#define RIO_RESETSTAT RIO_REG_BASE + 0x0100 /* READ: Reset Status (Jet boards only) */
59
60/* RIO_VPD_ROM definitions... */
61#define VPD_SLX_ID1 0x00 /* READ: Specialix Identifier #1 */
62#define VPD_SLX_ID2 0x01 /* READ: Specialix Identifier #2 */
63#define VPD_HW_REV 0x02 /* READ: Hardware Revision */
64#define VPD_HW_ASSEM 0x03 /* READ: Hardware Assembly Level */
65#define VPD_UNIQUEID4 0x04 /* READ: Unique Identifier #4 */
66#define VPD_UNIQUEID3 0x05 /* READ: Unique Identifier #3 */
67#define VPD_UNIQUEID2 0x06 /* READ: Unique Identifier #2 */
68#define VPD_UNIQUEID1 0x07 /* READ: Unique Identifier #1 */
69#define VPD_MANU_YEAR 0x08 /* READ: Year Of Manufacture (0 = 1970) */
70#define VPD_MANU_WEEK 0x09 /* READ: Week Of Manufacture (0 = week 1 Jan) */
71#define VPD_HWFEATURE1 0x0A /* READ: Hardware Feature Byte 1 */
72#define VPD_HWFEATURE2 0x0B /* READ: Hardware Feature Byte 2 */
73#define VPD_HWFEATURE3 0x0C /* READ: Hardware Feature Byte 3 */
74#define VPD_HWFEATURE4 0x0D /* READ: Hardware Feature Byte 4 */
75#define VPD_HWFEATURE5 0x0E /* READ: Hardware Feature Byte 5 */
76#define VPD_OEMID 0x0F /* READ: OEM Identifier */
77#define VPD_IDENT 0x10 /* READ: Identifier string (16 bytes) */
78#define VPD_IDENT_LEN 0x10
79
80/* VPD ROM Definitions... */
81#define SLX_ID1 0x4D
82#define SLX_ID2 0x98
83
84#define PRODUCT_ID(a) ((a>>4)&0xF) /* Use to obtain Product ID from VPD_UNIQUEID1 */
85
86#define ID_SX_ISA 0x2
87#define ID_RIO_EISA 0x3
88#define ID_SX_PCI 0x5
89#define ID_SX_EISA 0x7
90#define ID_RIO_RTA16 0x9
91#define ID_RIO_ISA 0xA
92#define ID_RIO_MCA 0xB
93#define ID_RIO_SBUS 0xC
94#define ID_RIO_PCI 0xD
95#define ID_RIO_RTA8 0xE
96
97/* Transputer bootstrap definitions... */
98
99#define BOOTLOADADDR (0x8000 - 6)
100#define BOOTINDICATE (0x8000 - 2)
101
102/* Firmware load position... */
103
104#define FIRMWARELOADADDR 0x7C00 /* Firmware is loaded _before_ this address */
105
106/*****************************************************************************
107***************************** *****************************
108***************************** RIO (Rev1) ISA *****************************
109***************************** *****************************
110*****************************************************************************/
111
112/* Control Register Definitions... */
113#define RIO_ISA_IDENT "JBJGPGGHINSMJPJR"
114
115#define RIO_ISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
116#define RIO_ISA_CFG_BUSENABLE 0x02 /* Enable processor bus */
117#define RIO_ISA_CFG_IRQMASK 0x30 /* Interrupt mask */
118#define RIO_ISA_CFG_IRQ12 0x10 /* Interrupt Level 12 */
119#define RIO_ISA_CFG_IRQ11 0x20 /* Interrupt Level 11 */
120#define RIO_ISA_CFG_IRQ9 0x30 /* Interrupt Level 9 */
121#define RIO_ISA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
122#define RIO_ISA_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */
123
124/*****************************************************************************
125***************************** *****************************
126***************************** RIO (Rev2) ISA *****************************
127***************************** *****************************
128*****************************************************************************/
129
130/* Control Register Definitions... */
131#define RIO_ISA2_IDENT "JBJGPGGHINSMJPJR"
132
133#define RIO_ISA2_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
134#define RIO_ISA2_CFG_BUSENABLE 0x02 /* Enable processor bus */
135#define RIO_ISA2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
136#define RIO_ISA2_CFG_16BIT 0x08 /* 16bit mode, else 8bit */
137#define RIO_ISA2_CFG_IRQMASK 0x30 /* Interrupt mask */
138#define RIO_ISA2_CFG_IRQ15 0x00 /* Interrupt Level 15 */
139#define RIO_ISA2_CFG_IRQ12 0x10 /* Interrupt Level 12 */
140#define RIO_ISA2_CFG_IRQ11 0x20 /* Interrupt Level 11 */
141#define RIO_ISA2_CFG_IRQ9 0x30 /* Interrupt Level 9 */
142#define RIO_ISA2_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
143#define RIO_ISA2_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */
144
145/*****************************************************************************
146***************************** ******************************
147***************************** RIO (Jet) ISA ******************************
148***************************** ******************************
149*****************************************************************************/
150
151/* Control Register Definitions... */
152#define RIO_ISA3_IDENT "JET HOST BY KEV#"
153
154#define RIO_ISA3_CFG_BUSENABLE 0x02 /* Enable processor bus */
155#define RIO_ISA3_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
156#define RIO_ISA32_CFG_IRQMASK 0xF30 /* Interrupt mask */
157#define RIO_ISA3_CFG_IRQ15 0xF0 /* Interrupt Level 15 */
158#define RIO_ISA3_CFG_IRQ12 0xC0 /* Interrupt Level 12 */
159#define RIO_ISA3_CFG_IRQ11 0xB0 /* Interrupt Level 11 */
160#define RIO_ISA3_CFG_IRQ10 0xA0 /* Interrupt Level 10 */
161#define RIO_ISA3_CFG_IRQ9 0x90 /* Interrupt Level 9 */
162
163/*****************************************************************************
164********************************* ********************************
165********************************* RIO MCA ********************************
166********************************* ********************************
167*****************************************************************************/
168
169/* Control Register Definitions... */
170#define RIO_MCA_IDENT "JBJGPGGHINSMJPJR"
171
172#define RIO_MCA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
173#define RIO_MCA_CFG_BUSENABLE 0x02 /* Enable processor bus */
174#define RIO_MCA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
175
176/*****************************************************************************
177******************************** ********************************
178******************************** RIO EISA ********************************
179******************************** ********************************
180*****************************************************************************/
181
182/* EISA Configuration Space Definitions... */
183#define EISA_PRODUCT_ID1 0xC80
184#define EISA_PRODUCT_ID2 0xC81
185#define EISA_PRODUCT_NUMBER 0xC82
186#define EISA_REVISION_NUMBER 0xC83
187#define EISA_CARD_ENABLE 0xC84
188#define EISA_VPD_UNIQUEID4 0xC88 /* READ: Unique Identifier #4 */
189#define EISA_VPD_UNIQUEID3 0xC8A /* READ: Unique Identifier #3 */
190#define EISA_VPD_UNIQUEID2 0xC90 /* READ: Unique Identifier #2 */
191#define EISA_VPD_UNIQUEID1 0xC92 /* READ: Unique Identifier #1 */
192#define EISA_VPD_MANU_YEAR 0xC98 /* READ: Year Of Manufacture (0 = 1970) */
193#define EISA_VPD_MANU_WEEK 0xC9A /* READ: Week Of Manufacture (0 = week 1 Jan) */
194#define EISA_MEM_ADDR_23_16 0xC00
195#define EISA_MEM_ADDR_31_24 0xC01
196#define EISA_RIO_CONFIG 0xC02 /* WRITE: Configuration Register */
197#define EISA_RIO_INTSET 0xC03 /* WRITE: Interrupt Set */
198#define EISA_RIO_INTRESET 0xC03 /* READ: Interrupt Reset */
199
200/* Control Register Definitions... */
201#define RIO_EISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
202#define RIO_EISA_CFG_LINK20 0x02 /* 20Mbps link, else 10Mbps */
203#define RIO_EISA_CFG_BUSENABLE 0x04 /* Enable processor bus */
204#define RIO_EISA_CFG_PROCRUN 0x08 /* Processor running, else reset */
205#define RIO_EISA_CFG_IRQMASK 0xF0 /* Interrupt mask */
206#define RIO_EISA_CFG_IRQ15 0xF0 /* Interrupt Level 15 */
207#define RIO_EISA_CFG_IRQ14 0xE0 /* Interrupt Level 14 */
208#define RIO_EISA_CFG_IRQ12 0xC0 /* Interrupt Level 12 */
209#define RIO_EISA_CFG_IRQ11 0xB0 /* Interrupt Level 11 */
210#define RIO_EISA_CFG_IRQ10 0xA0 /* Interrupt Level 10 */
211#define RIO_EISA_CFG_IRQ9 0x90 /* Interrupt Level 9 */
212#define RIO_EISA_CFG_IRQ7 0x70 /* Interrupt Level 7 */
213#define RIO_EISA_CFG_IRQ6 0x60 /* Interrupt Level 6 */
214#define RIO_EISA_CFG_IRQ5 0x50 /* Interrupt Level 5 */
215#define RIO_EISA_CFG_IRQ4 0x40 /* Interrupt Level 4 */
216#define RIO_EISA_CFG_IRQ3 0x30 /* Interrupt Level 3 */
217
218/*****************************************************************************
219******************************** ********************************
220******************************** RIO SBus ********************************
221******************************** ********************************
222*****************************************************************************/
223
224/* Control Register Definitions... */
225#define RIO_SBUS_IDENT "JBPGK#\0\0\0\0\0\0\0\0\0\0"
226
227#define RIO_SBUS_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
228#define RIO_SBUS_CFG_BUSENABLE 0x02 /* Enable processor bus */
229#define RIO_SBUS_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
230#define RIO_SBUS_CFG_IRQMASK 0x38 /* Interrupt mask */
231#define RIO_SBUS_CFG_IRQNONE 0x00 /* No Interrupt */
232#define RIO_SBUS_CFG_IRQ7 0x38 /* Interrupt Level 7 */
233#define RIO_SBUS_CFG_IRQ6 0x30 /* Interrupt Level 6 */
234#define RIO_SBUS_CFG_IRQ5 0x28 /* Interrupt Level 5 */
235#define RIO_SBUS_CFG_IRQ4 0x20 /* Interrupt Level 4 */
236#define RIO_SBUS_CFG_IRQ3 0x18 /* Interrupt Level 3 */
237#define RIO_SBUS_CFG_IRQ2 0x10 /* Interrupt Level 2 */
238#define RIO_SBUS_CFG_IRQ1 0x08 /* Interrupt Level 1 */
239#define RIO_SBUS_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
240#define RIO_SBUS_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */
241
242/*****************************************************************************
243********************************* ********************************
244********************************* RIO PCI ********************************
245********************************* ********************************
246*****************************************************************************/
247
248/* Control Register Definitions... */
249#define RIO_PCI_IDENT "ECDDPGJGJHJRGSK#"
250
251#define RIO_PCI_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
252#define RIO_PCI_CFG_BUSENABLE 0x02 /* Enable processor bus */
253#define RIO_PCI_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
254#define RIO_PCI_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
255#define RIO_PCI_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */
256
257/* PCI Definitions... */
258#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */
259#define SPX_DEVICE_ID 0x8000 /* RIO bridge boards */
260#define SPX_PLXDEVICE_ID 0x2000 /* PLX bridge boards */
261#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */
262#define RIO_SUB_SYS_ID 0x0800 /* RIO PCI board */
263
264/*****************************************************************************
265***************************** ******************************
266***************************** RIO (Jet) PCI ******************************
267***************************** ******************************
268*****************************************************************************/
269
270/* Control Register Definitions... */
271#define RIO_PCI2_IDENT "JET HOST BY KEV#"
272
273#define RIO_PCI2_CFG_BUSENABLE 0x02 /* Enable processor bus */
274#define RIO_PCI2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
275
276/* PCI Definitions... */
277#define RIO2_SUB_SYS_ID 0x0100 /* RIO (Jet) PCI board */
278
279#endif /*_rioboard_h */
280
281/* End of RIOBOARD.H */
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
new file mode 100644
index 000000000000..a8be11dfcba3
--- /dev/null
+++ b/drivers/char/rio/rioboot.c
@@ -0,0 +1,1360 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rioboot.c
24** SID : 1.3
25** Last Modified : 11/6/98 10:33:36
26** Retrieved : 11/6/98 10:33:48
27**
28** ident @(#)rioboot.c 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifdef SCCS_LABELS
34static char *_rioboot_c_sccs_ = "@(#)rioboot.c 1.3";
35#endif
36
37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <linux/interrupt.h>
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/string.h>
44#include <asm/semaphore.h>
45
46
47#include <linux/termios.h>
48#include <linux/serial.h>
49
50#include <linux/generic_serial.h>
51
52
53
54#include "linux_compat.h"
55#include "rio_linux.h"
56#include "typdef.h"
57#include "pkt.h"
58#include "daemon.h"
59#include "rio.h"
60#include "riospace.h"
61#include "top.h"
62#include "cmdpkt.h"
63#include "map.h"
64#include "riotypes.h"
65#include "rup.h"
66#include "port.h"
67#include "riodrvr.h"
68#include "rioinfo.h"
69#include "func.h"
70#include "errors.h"
71#include "pci.h"
72
73#include "parmmap.h"
74#include "unixrup.h"
75#include "board.h"
76#include "host.h"
77#include "error.h"
78#include "phb.h"
79#include "link.h"
80#include "cmdblk.h"
81#include "route.h"
82
83static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP );
84
85static uchar
86RIOAtVec2Ctrl[] =
87{
88 /* 0 */ INTERRUPT_DISABLE,
89 /* 1 */ INTERRUPT_DISABLE,
90 /* 2 */ INTERRUPT_DISABLE,
91 /* 3 */ INTERRUPT_DISABLE,
92 /* 4 */ INTERRUPT_DISABLE,
93 /* 5 */ INTERRUPT_DISABLE,
94 /* 6 */ INTERRUPT_DISABLE,
95 /* 7 */ INTERRUPT_DISABLE,
96 /* 8 */ INTERRUPT_DISABLE,
97 /* 9 */ IRQ_9|INTERRUPT_ENABLE,
98 /* 10 */ INTERRUPT_DISABLE,
99 /* 11 */ IRQ_11|INTERRUPT_ENABLE,
100 /* 12 */ IRQ_12|INTERRUPT_ENABLE,
101 /* 13 */ INTERRUPT_DISABLE,
102 /* 14 */ INTERRUPT_DISABLE,
103 /* 15 */ IRQ_15|INTERRUPT_ENABLE
104};
105
106/*
107** Load in the RTA boot code.
108*/
109int
110RIOBootCodeRTA(p, rbp)
111struct rio_info * p;
112struct DownLoad * rbp;
113{
114 int offset;
115
116 func_enter ();
117
118 /* Linux doesn't allow you to disable interrupts during a
119 "copyin". (Crash when a pagefault occurs). */
120 /* disable(oldspl); */
121
122 rio_dprintk (RIO_DEBUG_BOOT, "Data at user address 0x%x\n",(int)rbp->DataP);
123
124 /*
125 ** Check that we have set asside enough memory for this
126 */
127 if ( rbp->Count > SIXTY_FOUR_K ) {
128 rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n");
129 p->RIOError.Error = HOST_FILE_TOO_LARGE;
130 /* restore(oldspl); */
131 func_exit ();
132 return -ENOMEM;
133 }
134
135 if ( p->RIOBooting ) {
136 rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n");
137 p->RIOError.Error = BOOT_IN_PROGRESS;
138 /* restore(oldspl); */
139 func_exit ();
140 return -EBUSY;
141 }
142
143 /*
144 ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary,
145 ** so calculate how far we have to move the data up the buffer
146 ** to achieve this.
147 */
148 offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) %
149 RTA_BOOT_DATA_SIZE;
150
151 /*
152 ** Be clean, and clear the 'unused' portion of the boot buffer,
153 ** because it will (eventually) be part of the Rta run time environment
154 ** and so should be zeroed.
155 */
156 bzero( (caddr_t)p->RIOBootPackets, offset );
157
158 /*
159 ** Copy the data from user space.
160 */
161
162 if ( copyin((int)rbp->DataP,((caddr_t)(p->RIOBootPackets))+offset,
163 rbp->Count) ==COPYFAIL ) {
164 rio_dprintk (RIO_DEBUG_BOOT, "Bad data copy from user space\n");
165 p->RIOError.Error = COPYIN_FAILED;
166 /* restore(oldspl); */
167 func_exit ();
168 return -EFAULT;
169 }
170
171 /*
172 ** Make sure that our copy of the size includes that offset we discussed
173 ** earlier.
174 */
175 p->RIONumBootPkts = (rbp->Count+offset)/RTA_BOOT_DATA_SIZE;
176 p->RIOBootCount = rbp->Count;
177
178 /* restore(oldspl); */
179 func_exit();
180 return 0;
181}
182
183void rio_start_card_running (struct Host * HostP)
184{
185 func_enter ();
186
187 switch ( HostP->Type ) {
188 case RIO_AT:
189 rio_dprintk (RIO_DEBUG_BOOT, "Start ISA card running\n");
190 WBYTE(HostP->Control,
191 BOOT_FROM_RAM | EXTERNAL_BUS_ON
192 | HostP->Mode
193 | RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
194 break;
195
196#ifdef FUTURE_RELEASE
197 case RIO_MCA:
198 /*
199 ** MCA handles IRQ vectors differently, so we don't write
200 ** them to this register.
201 */
202 rio_dprintk (RIO_DEBUG_BOOT, "Start MCA card running\n");
203 WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
204 break;
205
206 case RIO_EISA:
207 /*
208 ** EISA is totally different and expects OUTBZs to turn it on.
209 */
210 rio_dprintk (RIO_DEBUG_BOOT, "Start EISA card running\n");
211 OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
212 break;
213#endif
214
215 case RIO_PCI:
216 /*
217 ** PCI is much the same as MCA. Everything is once again memory
218 ** mapped, so we are writing to memory registers instead of io
219 ** ports.
220 */
221 rio_dprintk (RIO_DEBUG_BOOT, "Start PCI card running\n");
222 WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
223 break;
224 default:
225 rio_dprintk (RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type);
226 break;
227 }
228/*
229 printk (KERN_INFO "Done with starting the card\n");
230 func_exit ();
231*/
232 return;
233}
234
235/*
236** Load in the host boot code - load it directly onto all halted hosts
237** of the correct type.
238**
239** Put your rubber pants on before messing with this code - even the magic
240** numbers have trouble understanding what they are doing here.
241*/
242int
243RIOBootCodeHOST(p, rbp)
244struct rio_info * p;
245register struct DownLoad *rbp;
246{
247 register struct Host *HostP;
248 register caddr_t Cad;
249 register PARM_MAP *ParmMapP;
250 register int RupN;
251 int PortN;
252 uint host;
253 caddr_t StartP;
254 BYTE *DestP;
255 int wait_count;
256 ushort OldParmMap;
257 ushort offset; /* It is very important that this is a ushort */
258 /* uint byte; */
259 caddr_t DownCode = NULL;
260 unsigned long flags;
261
262 HostP = NULL; /* Assure the compiler we've initialized it */
263 for ( host=0; host<p->RIONumHosts; host++ ) {
264 rio_dprintk (RIO_DEBUG_BOOT, "Attempt to boot host %d\n",host);
265 HostP = &p->RIOHosts[host];
266
267 rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
268 HostP->Type, HostP->Mode, HostP->Ivec);
269
270
271 if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) {
272 rio_dprintk (RIO_DEBUG_BOOT, "%s %d already running\n","Host",host);
273 continue;
274 }
275
276 /*
277 ** Grab a 32 bit pointer to the card.
278 */
279 Cad = HostP->Caddr;
280
281 /*
282 ** We are going to (try) and load in rbp->Count bytes.
283 ** The last byte will reside at p->RIOConf.HostLoadBase-1;
284 ** Therefore, we need to start copying at address
285 ** (caddr+p->RIOConf.HostLoadBase-rbp->Count)
286 */
287 StartP = (caddr_t)&Cad[p->RIOConf.HostLoadBase-rbp->Count];
288
289 rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for host is 0x%x\n", (int)Cad );
290 rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for download is 0x%x\n", (int)StartP);
291 rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
292 rio_dprintk (RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count);
293
294 if ( p->RIOConf.HostLoadBase < rbp->Count ) {
295 rio_dprintk (RIO_DEBUG_BOOT, "Bin too large\n");
296 p->RIOError.Error = HOST_FILE_TOO_LARGE;
297 func_exit ();
298 return -EFBIG;
299 }
300 /*
301 ** Ensure that the host really is stopped.
302 ** Disable it's external bus & twang its reset line.
303 */
304 RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );
305
306 /*
307 ** Copy the data directly from user space to the SRAM.
308 ** This ain't going to be none too clever if the download
309 ** code is bigger than this segment.
310 */
311 rio_dprintk (RIO_DEBUG_BOOT, "Copy in code\n");
312
313 /*
314 ** PCI hostcard can't cope with 32 bit accesses and so need to copy
315 ** data to a local buffer, and then dripfeed the card.
316 */
317 if ( HostP->Type == RIO_PCI ) {
318 /* int offset; */
319
320 DownCode = sysbrk(rbp->Count);
321 if ( !DownCode ) {
322 rio_dprintk (RIO_DEBUG_BOOT, "No system memory available\n");
323 p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY;
324 func_exit ();
325 return -ENOMEM;
326 }
327 bzero(DownCode, rbp->Count);
328
329 if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) {
330 rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
331 sysfree( DownCode, rbp->Count );
332 p->RIOError.Error = COPYIN_FAILED;
333 func_exit ();
334 return -EFAULT;
335 }
336
337 HostP->Copy( DownCode, StartP, rbp->Count );
338
339 sysfree( DownCode, rbp->Count );
340 }
341 else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) {
342 rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
343 p->RIOError.Error = COPYIN_FAILED;
344 func_exit ();
345 return -EFAULT;
346 }
347
348 rio_dprintk (RIO_DEBUG_BOOT, "Copy completed\n");
349
350 /*
351 ** S T O P !
352 **
353 ** Upto this point the code has been fairly rational, and possibly
354 ** even straight forward. What follows is a pile of crud that will
355 ** magically turn into six bytes of transputer assembler. Normally
356 ** you would expect an array or something, but, being me, I have
357 ** chosen [been told] to use a technique whereby the startup code
358 ** will be correct if we change the loadbase for the code. Which
359 ** brings us onto another issue - the loadbase is the *end* of the
360 ** code, not the start.
361 **
362 ** If I were you I wouldn't start from here.
363 */
364
365 /*
366 ** We now need to insert a short boot section into
367 ** the memory at the end of Sram2. This is normally (de)composed
368 ** of the last eight bytes of the download code. The
369 ** download has been assembled/compiled to expect to be
370 ** loaded from 0x7FFF downwards. We have loaded it
371 ** at some other address. The startup code goes into the small
372 ** ram window at Sram2, in the last 8 bytes, which are really
373 ** at addresses 0x7FF8-0x7FFF.
374 **
375 ** If the loadbase is, say, 0x7C00, then we need to branch to
376 ** address 0x7BFE to run the host.bin startup code. We assemble
377 ** this jump manually.
378 **
379 ** The two byte sequence 60 08 is loaded into memory at address
380 ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0,
381 ** which adds '0' to the .O register, complements .O, and then shifts
382 ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will
383 ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new
384 ** location. Now, the branch starts from the value of .PC (or .IP or
385 ** whatever the bloody register is called on this chip), and the .PC
386 ** will be pointing to the location AFTER the branch, in this case
387 ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8.
388 **
389 ** A long branch is coded at 0x7FF8. This consists of loading a four
390 ** byte offset into .O using nfix (as above) and pfix operators. The
391 ** pfix operates in exactly the same way as the nfix operator, but
392 ** without the complement operation. The offset, of course, must be
393 ** relative to the address of the byte AFTER the branch instruction,
394 ** which will be (urm) 0x7FFC, so, our final destination of the branch
395 ** (loadbase-2), has to be reached from here. Imagine that the loadbase
396 ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which
397 ** is the first byte of the initial two byte short local branch of the
398 ** download code).
399 **
400 ** To code a jump from 0x7FFC (which is where the branch will start
401 ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)=
402 ** 0x7BFE.
403 ** This will be coded as four bytes:
404 ** 60 2C 20 02
405 ** being nfix .O+0
406 ** pfix .O+C
407 ** pfix .O+0
408 ** jump .O+2
409 **
410 ** The nfix operator is used, so that the startup code will be
411 ** compatible with the whole Tp family. (lies, damn lies, it'll never
412 ** work in a month of Sundays).
413 **
414 ** The nfix nyble is the 1s complement of the nyble value you
415 ** want to load - in this case we wanted 'F' so we nfix loaded '0'.
416 */
417
418
419 /*
420 ** Dest points to the top 8 bytes of Sram2. The Tp jumps
421 ** to 0x7FFE at reset time, and starts executing. This is
422 ** a short branch to 0x7FF8, where a long branch is coded.
423 */
424
425 DestP = (BYTE *)&Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */
426
427#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */
428#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */
429#define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */
430
431 /*
432 ** 0x7FFC is the address of the location following the last byte of
433 ** the four byte jump instruction.
434 ** READ THE ABOVE COMMENTS
435 **
436 ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about.
437 ** Memsize is 64K for this range of Tp, so offset is a short (unsigned,
438 ** cos I don't understand 2's complement).
439 */
440 offset = (p->RIOConf.HostLoadBase-2)-0x7FFC;
441 WBYTE( DestP[0] , NFIX(((ushort)(~offset) >> (ushort)12) & 0xF) );
442 WBYTE( DestP[1] , PFIX(( offset >> 8) & 0xF) );
443 WBYTE( DestP[2] , PFIX(( offset >> 4) & 0xF) );
444 WBYTE( DestP[3] , JUMP( offset & 0xF) );
445
446 WBYTE( DestP[6] , NFIX(0) );
447 WBYTE( DestP[7] , JUMP(8) );
448
449 rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
450 rio_dprintk (RIO_DEBUG_BOOT, "startup offset is 0x%x\n",offset);
451
452 /*
453 ** Flag what is going on
454 */
455 HostP->Flags &= ~RUN_STATE;
456 HostP->Flags |= RC_STARTUP;
457
458 /*
459 ** Grab a copy of the current ParmMap pointer, so we
460 ** can tell when it has changed.
461 */
462 OldParmMap = RWORD(HostP->__ParmMapR);
463
464 rio_dprintk (RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n",OldParmMap);
465
466 /*
467 ** And start it running (I hope).
468 ** As there is nothing dodgy or obscure about the
469 ** above code, this is guaranteed to work every time.
470 */
471 rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
472 HostP->Type, HostP->Mode, HostP->Ivec);
473
474 rio_start_card_running(HostP);
475
476 rio_dprintk (RIO_DEBUG_BOOT, "Set control port\n");
477
478 /*
479 ** Now, wait for upto five seconds for the Tp to setup the parmmap
480 ** pointer:
481 */
482 for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&
483 (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
484 rio_dprintk (RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR));
485 delay(HostP, HUNDRED_MS);
486
487 }
488
489 /*
490 ** If the parmmap pointer is unchanged, then the host code
491 ** has crashed & burned in a really spectacular way
492 */
493 if ( RWORD(HostP->__ParmMapR) == OldParmMap ) {
494 rio_dprintk (RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR));
495 rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n");
496
497#define HOST_DISABLE \
498 HostP->Flags &= ~RUN_STATE; \
499 HostP->Flags |= RC_STUFFED; \
500 RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );\
501 continue
502
503 HOST_DISABLE;
504 }
505
506 rio_dprintk (RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR));
507
508 /*
509 ** Well, the board thought it was OK, and setup its parmmap
510 ** pointer. For the time being, we will pretend that this
511 ** board is running, and check out what the error flag says.
512 */
513
514 /*
515 ** Grab a 32 bit pointer to the parmmap structure
516 */
517 ParmMapP = (PARM_MAP *)RIO_PTR(Cad,RWORD(HostP->__ParmMapR));
518 rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
519 ParmMapP = (PARM_MAP *)((unsigned long)Cad +
520 (unsigned long)((RWORD((HostP->__ParmMapR))) & 0xFFFF));
521 rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
522
523 /*
524 ** The links entry should be 0xFFFF; we set it up
525 ** with a mask to say how many PHBs to use, and
526 ** which links to use.
527 */
528 if ( (RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF ) {
529 rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
530 rio_dprintk (RIO_DEBUG_BOOT, "Links = 0x%x\n",RWORD(ParmMapP->links));
531 HOST_DISABLE;
532 }
533
534 WWORD(ParmMapP->links , RIO_LINK_ENABLE);
535
536 /*
537 ** now wait for the card to set all the parmmap->XXX stuff
538 ** this is a wait of upto two seconds....
539 */
540 rio_dprintk (RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n",p->RIOConf.StartupTime);
541 HostP->timeout_id = 0;
542 for ( wait_count=0; (wait_count<p->RIOConf.StartupTime) &&
543 !RWORD(ParmMapP->init_done); wait_count++ ) {
544 rio_dprintk (RIO_DEBUG_BOOT, "Waiting for init_done\n");
545 delay(HostP, HUNDRED_MS);
546 }
547 rio_dprintk (RIO_DEBUG_BOOT, "OK! init_done!\n");
548
549 if (RWORD(ParmMapP->error) != E_NO_ERROR ||
550 !RWORD(ParmMapP->init_done) ) {
551 rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
552 rio_dprintk (RIO_DEBUG_BOOT, "Timedout waiting for init_done\n");
553 HOST_DISABLE;
554 }
555
556 rio_dprintk (RIO_DEBUG_BOOT, "Got init_done\n");
557
558 /*
559 ** It runs! It runs!
560 */
561 rio_dprintk (RIO_DEBUG_BOOT, "Host ID %x Running\n",HostP->UniqueNum);
562
563 /*
564 ** set the time period between interrupts.
565 */
566 WWORD(ParmMapP->timer, (short)p->RIOConf.Timer );
567
568 /*
569 ** Translate all the 16 bit pointers in the __ParmMapR into
570 ** 32 bit pointers for the driver.
571 */
572 HostP->ParmMapP = ParmMapP;
573 HostP->PhbP = (PHB*)RIO_PTR(Cad,RWORD(ParmMapP->phb_ptr));
574 HostP->RupP = (RUP*)RIO_PTR(Cad,RWORD(ParmMapP->rups));
575 HostP->PhbNumP = (ushort*)RIO_PTR(Cad,RWORD(ParmMapP->phb_num_ptr));
576 HostP->LinkStrP = (LPB*)RIO_PTR(Cad,RWORD(ParmMapP->link_str_ptr));
577
578 /*
579 ** point the UnixRups at the real Rups
580 */
581 for ( RupN = 0; RupN<MAX_RUP; RupN++ ) {
582 HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN];
583 HostP->UnixRups[RupN].Id = RupN+1;
584 HostP->UnixRups[RupN].BaseSysPort = NO_PORT;
585 spin_lock_init(&HostP->UnixRups[RupN].RupLock);
586 }
587
588 for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) {
589 HostP->UnixRups[RupN+MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup;
590 HostP->UnixRups[RupN+MAX_RUP].Id = 0;
591 HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT;
592 spin_lock_init(&HostP->UnixRups[RupN+MAX_RUP].RupLock);
593 }
594
595 /*
596 ** point the PortP->Phbs at the real Phbs
597 */
598 for ( PortN=p->RIOFirstPortsMapped;
599 PortN<p->RIOLastPortsMapped+PORTS_PER_RTA; PortN++ ) {
600 if ( p->RIOPortp[PortN]->HostP == HostP ) {
601 struct Port *PortP = p->RIOPortp[PortN];
602 struct PHB *PhbP;
603 /* int oldspl; */
604
605 if ( !PortP->Mapped )
606 continue;
607
608 PhbP = &HostP->PhbP[PortP->HostPort];
609 rio_spin_lock_irqsave(&PortP->portSem, flags);
610
611 PortP->PhbP = PhbP;
612
613 PortP->TxAdd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_add));
614 PortP->TxStart = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_start));
615 PortP->TxEnd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_end));
616 PortP->RxRemove = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_remove));
617 PortP->RxStart = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_start));
618 PortP->RxEnd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_end));
619
620 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
621 /*
622 ** point the UnixRup at the base SysPort
623 */
624 if ( !(PortN % PORTS_PER_RTA) )
625 HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN;
626 }
627 }
628
629 rio_dprintk (RIO_DEBUG_BOOT, "Set the card running... \n");
630 /*
631 ** last thing - show the world that everything is in place
632 */
633 HostP->Flags &= ~RUN_STATE;
634 HostP->Flags |= RC_RUNNING;
635 }
636 /*
637 ** MPX always uses a poller. This is actually patched into the system
638 ** configuration and called directly from each clock tick.
639 **
640 */
641 p->RIOPolling = 1;
642
643 p->RIOSystemUp++;
644
645 rio_dprintk (RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec);
646 func_exit ();
647 return 0;
648}
649
650
651
652/*
653** Boot an RTA. If we have successfully processed this boot, then
654** return 1. If we havent, then return 0.
655*/
656int
657RIOBootRup( p, Rup, HostP, PacketP)
658struct rio_info * p;
659uint Rup;
660struct Host *HostP;
661struct PKT *PacketP;
662{
663 struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
664 struct PktCmd_M *PktReplyP;
665 struct CmdBlk *CmdBlkP;
666 uint sequence;
667
668#ifdef CHECK
669 CheckHost(Host);
670 CheckRup(Rup);
671 CheckHostP(HostP);
672 CheckPacketP(PacketP);
673#endif
674
675 /*
676 ** If we haven't been told what to boot, we can't boot it.
677 */
678 if ( p->RIONumBootPkts == 0 ) {
679 rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n");
680 return 0;
681 }
682
683 /* rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_BOOT,"Incoming command packet\n"); */
684 /* ShowPacket( DBG_BOOT, PacketP ); */
685
686 /*
687 ** Special case of boot completed - if we get one of these then we
688 ** don't need a command block. For all other cases we do, so handle
689 ** this first and then get a command block, then handle every other
690 ** case, relinquishing the command block if disaster strikes!
691 */
692 if ( (RBYTE(PacketP->len) & PKT_CMD_BIT) &&
693 (RBYTE(PktCmdP->Command)==BOOT_COMPLETED) )
694 return RIOBootComplete(p, HostP, Rup, PktCmdP );
695
696 /*
697 ** try to unhook a command block from the command free list.
698 */
699 if ( !(CmdBlkP = RIOGetCmdBlk()) ) {
700 rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n");
701 return 0;
702 }
703
704 /*
705 ** Fill in the default info on the command block
706 */
707 CmdBlkP->Packet.dest_unit = Rup < (ushort)MAX_RUP ? Rup : 0;
708 CmdBlkP->Packet.dest_port = BOOT_RUP;
709 CmdBlkP->Packet.src_unit = 0;
710 CmdBlkP->Packet.src_port = BOOT_RUP;
711
712 CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL;
713 PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data;
714
715 /*
716 ** process COMMANDS on the boot rup!
717 */
718 if ( RBYTE(PacketP->len) & PKT_CMD_BIT ) {
719 /*
720 ** We only expect one type of command - a BOOT_REQUEST!
721 */
722 if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) {
723 rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n",
724 PktCmdP->Command,Rup,HostP-p->RIOHosts);
725 ShowPacket( DBG_BOOT, PacketP );
726 RIOFreeCmdBlk( CmdBlkP );
727 return 1;
728 }
729
730 /*
731 ** Build a Boot Sequence command block
732 **
733 ** 02.03.1999 ARG - ESIL 0820 fix
734 ** We no longer need to use "Boot Mode", we'll always allow
735 ** boot requests - the boot will not complete if the device
736 ** appears in the bindings table.
737 ** So, this conditional is not required ...
738 **
739 if (p->RIOBootMode == RC_BOOT_NONE)
740 **
741 ** If the system is in slave mode, and a boot request is
742 ** received, set command to BOOT_ABORT so that the boot
743 ** will not complete.
744 **
745 PktReplyP->Command = BOOT_ABORT;
746 else
747 **
748 ** We'll just (always) set the command field in packet reply
749 ** to allow an attempted boot sequence :
750 */
751 PktReplyP->Command = BOOT_SEQUENCE;
752
753 PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts;
754 PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase;
755 PktReplyP->BootSequence.CodeSize = p->RIOBootCount;
756
757 CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT;
758
759 bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4);
760
761 rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
762 HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts,
763 p->RIOConf.RtaLoadBase);
764
765 /*
766 ** If this host is in slave mode, send the RTA an invalid boot
767 ** sequence command block to force it to kill the boot. We wait
768 ** for half a second before sending this packet to prevent the RTA
769 ** attempting to boot too often. The master host should then grab
770 ** the RTA and make it its own.
771 */
772 p->RIOBooting++;
773 RIOQueueCmdBlk( HostP, Rup, CmdBlkP );
774 return 1;
775 }
776
777 /*
778 ** It is a request for boot data.
779 */
780 sequence = RWORD(PktCmdP->Sequence);
781
782 rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup);
783
784 if ( sequence >= p->RIONumBootPkts ) {
785 rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence,
786 p->RIONumBootPkts);
787 ShowPacket( DBG_BOOT, PacketP );
788 }
789
790 PktReplyP->Sequence = sequence;
791
792 bcopy( p->RIOBootPackets[ p->RIONumBootPkts - sequence - 1 ],
793 PktReplyP->BootData, RTA_BOOT_DATA_SIZE );
794
795 CmdBlkP->Packet.len = PKT_MAX_DATA_LEN;
796 ShowPacket( DBG_BOOT, &CmdBlkP->Packet );
797 RIOQueueCmdBlk( HostP, Rup, CmdBlkP );
798 return 1;
799}
800
801/*
802** This function is called when an RTA been booted.
803** If booted by a host, HostP->HostUniqueNum is the booting host.
804** If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA.
805** RtaUniq is the booted RTA.
806*/
807static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP )
808{
809 struct Map *MapP = NULL;
810 struct Map *MapP2 = NULL;
811 int Flag;
812 int found;
813 int host, rta;
814 int EmptySlot = -1;
815 int entry, entry2;
816 char *MyType, *MyName;
817 uint MyLink;
818 ushort RtaType;
819 uint RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) +
820 (RBYTE(PktCmdP->UniqNum[1]) << 8) +
821 (RBYTE(PktCmdP->UniqNum[2]) << 16) +
822 (RBYTE(PktCmdP->UniqNum[3]) << 24);
823
824 /* Was RIOBooting-- . That's bad. If an RTA sends two of them, the
825 driver will never think that the RTA has booted... -- REW */
826 p->RIOBooting = 0;
827
828 rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting);
829
830 /*
831 ** Determine type of unit (16/8 port RTA).
832 */
833 RtaType = GetUnitType(RtaUniq);
834 if ( Rup >= (ushort)MAX_RUP ) {
835 rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n",
836 HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A');
837 } else {
838 rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n",
839 HostP->Mapping[Rup].Name, 8 * RtaType,
840 RBYTE(PktCmdP->LinkNum)+'A');
841 }
842
843 rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq);
844
845 if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) )
846 {
847 rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n");
848 return TRUE;
849 }
850
851 /*
852 ** If this RTA has just booted an RTA which doesn't belong to this
853 ** system, or the system is in slave mode, do not attempt to create
854 ** a new table entry for it.
855 */
856 if (!RIOBootOk(p, HostP, RtaUniq))
857 {
858 MyLink = RBYTE(PktCmdP->LinkNum);
859 if (Rup < (ushort) MAX_RUP)
860 {
861 /*
862 ** RtaUniq was clone booted (by this RTA). Instruct this RTA
863 ** to hold off further attempts to boot on this link for 30
864 ** seconds.
865 */
866 if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink))
867 {
868 rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n",
869 'A' + MyLink);
870 }
871 }
872 else
873 {
874 /*
875 ** RtaUniq was booted by this host. Set the booting link
876 ** to hold off for 30 seconds to give another unit a
877 ** chance to boot it.
878 */
879 WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30);
880 }
881 rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n",
882 RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum);
883 return TRUE;
884 }
885
886 /*
887 ** Check for a SLOT_IN_USE entry for this RTA attached to the
888 ** current host card in the driver table.
889 **
890 ** If it exists, make a note that we have booted it. Other parts of
891 ** the driver are interested in this information at a later date,
892 ** in particular when the booting RTA asks for an ID for this unit,
893 ** we must have set the BOOTED flag, and the NEWBOOT flag is used
894 ** to force an open on any ports that where previously open on this
895 ** unit.
896 */
897 for ( entry=0; entry<MAX_RUP; entry++ )
898 {
899 uint sysport;
900
901 if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) &&
902 (HostP->Mapping[entry].RtaUniqueNum==RtaUniq))
903 {
904 HostP->Mapping[entry].Flags |= RTA_BOOTED|RTA_NEWBOOT;
905#if NEED_TO_FIX
906 RIO_SV_BROADCAST(HostP->svFlags[entry]);
907#endif
908 if ( (sysport=HostP->Mapping[entry].SysPort) != NO_PORT )
909 {
910 if ( sysport < p->RIOFirstPortsBooted )
911 p->RIOFirstPortsBooted = sysport;
912 if ( sysport > p->RIOLastPortsBooted )
913 p->RIOLastPortsBooted = sysport;
914 /*
915 ** For a 16 port RTA, check the second bank of 8 ports
916 */
917 if (RtaType == TYPE_RTA16)
918 {
919 entry2 = HostP->Mapping[entry].ID2 - 1;
920 HostP->Mapping[entry2].Flags |= RTA_BOOTED|RTA_NEWBOOT;
921#if NEED_TO_FIX
922 RIO_SV_BROADCAST(HostP->svFlags[entry2]);
923#endif
924 sysport = HostP->Mapping[entry2].SysPort;
925 if ( sysport < p->RIOFirstPortsBooted )
926 p->RIOFirstPortsBooted = sysport;
927 if ( sysport > p->RIOLastPortsBooted )
928 p->RIOLastPortsBooted = sysport;
929 }
930 }
931 if (RtaType == TYPE_RTA16) {
932 rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n",
933 entry+1, entry2+1);
934 } else {
935 rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given ID %d\n",entry+1);
936 }
937 return TRUE;
938 }
939 }
940
941 rio_dprintk (RIO_DEBUG_BOOT, "RTA not configured for this host\n");
942
943 if ( Rup >= (ushort)MAX_RUP )
944 {
945 /*
946 ** It was a host that did the booting
947 */
948 MyType = "Host";
949 MyName = HostP->Name;
950 }
951 else
952 {
953 /*
954 ** It was an RTA that did the booting
955 */
956 MyType = "RTA";
957 MyName = HostP->Mapping[Rup].Name;
958 }
959#ifdef CHECK
960 CheckString(MyType);
961 CheckString(MyName);
962#endif
963
964 MyLink = RBYTE(PktCmdP->LinkNum);
965
966 /*
967 ** There is no SLOT_IN_USE entry for this RTA attached to the current
968 ** host card in the driver table.
969 **
970 ** Check for a SLOT_TENTATIVE entry for this RTA attached to the
971 ** current host card in the driver table.
972 **
973 ** If we find one, then we re-use that slot.
974 */
975 for ( entry=0; entry<MAX_RUP; entry++ )
976 {
977 if ( (HostP->Mapping[entry].Flags & SLOT_TENTATIVE) &&
978 (HostP->Mapping[entry].RtaUniqueNum == RtaUniq) )
979 {
980 if (RtaType == TYPE_RTA16)
981 {
982 entry2 = HostP->Mapping[entry].ID2 - 1;
983 if ( (HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) &&
984 (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq) )
985 rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n",
986 entry, entry2);
987 else
988 continue;
989 }
990 else
991 rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n",entry);
992 if (! p->RIONoMessage)
993 cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A');
994 return TRUE;
995 }
996 }
997
998 /*
999 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA
1000 ** attached to the current host card in the driver table.
1001 **
1002 ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another
1003 ** host for this RTA in the driver table.
1004 **
1005 ** For a SLOT_IN_USE entry on another host, we need to delete the RTA
1006 ** entry from the other host and add it to this host (using some of
1007 ** the functions from table.c which do this).
1008 ** For a SLOT_TENTATIVE entry on another host, we must cope with the
1009 ** following scenario:
1010 **
1011 ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry
1012 ** in table)
1013 ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE
1014 ** entries)
1015 ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE)
1016 ** + Unplug RTA and plug back into host A.
1017 ** + Configure RTA on host A. We now have the same RTA configured
1018 ** with different ports on two different hosts.
1019 */
1020 rio_dprintk (RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq );
1021 found = 0;
1022 Flag = 0; /* Convince the compiler this variable is initialized */
1023 for ( host = 0; !found && (host < p->RIONumHosts); host++ )
1024 {
1025 for ( rta=0; rta<MAX_RUP; rta++ )
1026 {
1027 if ((p->RIOHosts[host].Mapping[rta].Flags &
1028 (SLOT_IN_USE | SLOT_TENTATIVE)) &&
1029 (p->RIOHosts[host].Mapping[rta].RtaUniqueNum==RtaUniq))
1030 {
1031 Flag = p->RIOHosts[host].Mapping[rta].Flags;
1032 MapP = &p->RIOHosts[host].Mapping[rta];
1033 if (RtaType == TYPE_RTA16)
1034 {
1035 MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1];
1036 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n",
1037 rta+1, MapP->ID2, p->RIOHosts[host].Name);
1038 }
1039 else
1040 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n",
1041 rta+1, p->RIOHosts[host].Name);
1042 found = 1;
1043 break;
1044 }
1045 }
1046 }
1047
1048 /*
1049 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA
1050 ** attached to the current host card in the driver table.
1051 **
1052 ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on
1053 ** another host for this RTA in the driver table...
1054 **
1055 ** Check for a SLOT_IN_USE entry for this RTA in the config table.
1056 */
1057 if ( !MapP )
1058 {
1059 rio_dprintk (RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n",RtaUniq);
1060 for ( rta=0; rta < TOTAL_MAP_ENTRIES; rta++ )
1061 {
1062 rio_dprintk (RIO_DEBUG_BOOT, "Check table entry %d (%x)",
1063 rta,
1064 p->RIOSavedTable[rta].RtaUniqueNum);
1065
1066 if ( (p->RIOSavedTable[rta].Flags & SLOT_IN_USE) &&
1067 (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq) )
1068 {
1069 MapP = &p->RIOSavedTable[rta];
1070 Flag = p->RIOSavedTable[rta].Flags;
1071 if (RtaType == TYPE_RTA16)
1072 {
1073 for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES;
1074 entry2++)
1075 {
1076 if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq)
1077 break;
1078 }
1079 MapP2 = &p->RIOSavedTable[entry2];
1080 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n",
1081 rta, entry2);
1082 }
1083 else
1084 rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta);
1085 break;
1086 }
1087 }
1088 }
1089
1090 /*
1091 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA
1092 ** attached to the current host card in the driver table.
1093 **
1094 ** We may have found a SLOT_IN_USE entry on another host for this
1095 ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry
1096 ** on another host for this RTA in the driver table.
1097 **
1098 ** Check the driver table for room to fit this newly discovered RTA.
1099 ** RIOFindFreeID() first looks for free slots and if it does not
1100 ** find any free slots it will then attempt to oust any
1101 ** tentative entry in the table.
1102 */
1103 EmptySlot = 1;
1104 if (RtaType == TYPE_RTA16)
1105 {
1106 if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0)
1107 {
1108 RIODefaultName(p, HostP, entry);
1109 FillSlot(entry, entry2, RtaUniq, HostP);
1110 EmptySlot = 0;
1111 }
1112 }
1113 else
1114 {
1115 if (RIOFindFreeID(p, HostP, &entry, NULL) == 0)
1116 {
1117 RIODefaultName(p, HostP, entry);
1118 FillSlot(entry, 0, RtaUniq, HostP);
1119 EmptySlot = 0;
1120 }
1121 }
1122
1123 /*
1124 ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA
1125 ** attached to the current host card in the driver table.
1126 **
1127 ** If we found a SLOT_IN_USE entry on another host for this
1128 ** RTA in the config or driver table, and there are enough free
1129 ** slots in the driver table, then we need to move it over and
1130 ** delete it from the other host.
1131 ** If we found a SLOT_TENTATIVE entry on another host for this
1132 ** RTA in the driver table, just delete the other host entry.
1133 */
1134 if (EmptySlot == 0)
1135 {
1136 if ( MapP )
1137 {
1138 if (Flag & SLOT_IN_USE)
1139 {
1140 rio_dprintk (RIO_DEBUG_BOOT,
1141 "This RTA configured on another host - move entry to current host (1)\n");
1142 HostP->Mapping[entry].SysPort = MapP->SysPort;
1143 CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN );
1144 HostP->Mapping[entry].Flags =
1145 SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT;
1146#if NEED_TO_FIX
1147 RIO_SV_BROADCAST(HostP->svFlags[entry]);
1148#endif
1149 RIOReMapPorts( p, HostP, &HostP->Mapping[entry] );
1150 if ( HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted )
1151 p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort;
1152 if ( HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted )
1153 p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort;
1154 rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name);
1155 }
1156 else
1157 {
1158 rio_dprintk (RIO_DEBUG_BOOT,
1159 "This RTA has a tentative entry on another host - delete that entry (1)\n");
1160 HostP->Mapping[entry].Flags =
1161 SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT;
1162#if NEED_TO_FIX
1163 RIO_SV_BROADCAST(HostP->svFlags[entry]);
1164#endif
1165 }
1166 if (RtaType == TYPE_RTA16)
1167 {
1168 if (Flag & SLOT_IN_USE)
1169 {
1170 HostP->Mapping[entry2].Flags = SLOT_IN_USE |
1171 RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT;
1172#if NEED_TO_FIX
1173 RIO_SV_BROADCAST(HostP->svFlags[entry2]);
1174#endif
1175 HostP->Mapping[entry2].SysPort = MapP2->SysPort;
1176 /*
1177 ** Map second block of ttys for 16 port RTA
1178 */
1179 RIOReMapPorts( p, HostP, &HostP->Mapping[entry2] );
1180 if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted)
1181 p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort;
1182 if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted)
1183 p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort;
1184 rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",
1185 (int)HostP->Mapping[entry2].SysPort,
1186 HostP->Mapping[entry].Name);
1187 }
1188 else
1189 HostP->Mapping[entry2].Flags = SLOT_TENTATIVE |
1190 RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT;
1191#if NEED_TO_FIX
1192 RIO_SV_BROADCAST(HostP->svFlags[entry2]);
1193#endif
1194 bzero( (caddr_t)MapP2, sizeof(struct Map) );
1195 }
1196 bzero( (caddr_t)MapP, sizeof(struct Map) );
1197 if (! p->RIONoMessage)
1198 cprintf("An orphaned RTA has been adopted by %s '%s' (%c).\n",MyType,MyName,MyLink+'A');
1199 }
1200 else if (! p->RIONoMessage)
1201 cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A');
1202 RIOSetChange(p);
1203 return TRUE;
1204 }
1205
1206 /*
1207 ** There is no room in the driver table to make an entry for the
1208 ** booted RTA. Keep a note of its Uniq Num in the overflow table,
1209 ** so we can ignore it's ID requests.
1210 */
1211 if (! p->RIONoMessage)
1212 cprintf("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n",MyType,MyName,MyLink+'A');
1213 for ( entry=0; entry<HostP->NumExtraBooted; entry++ )
1214 {
1215 if ( HostP->ExtraUnits[entry] == RtaUniq )
1216 {
1217 /*
1218 ** already got it!
1219 */
1220 return TRUE;
1221 }
1222 }
1223 /*
1224 ** If there is room, add the unit to the list of extras
1225 */
1226 if ( HostP->NumExtraBooted < MAX_EXTRA_UNITS )
1227 HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq;
1228 return TRUE;
1229}
1230
1231
1232/*
1233** If the RTA or its host appears in the RIOBindTab[] structure then
1234** we mustn't boot the RTA and should return FALSE.
1235** This operation is slightly different from the other drivers for RIO
1236** in that this is designed to work with the new utilities
1237** not config.rio and is FAR SIMPLER.
1238** We no longer support the RIOBootMode variable. It is all done from the
1239** "boot/noboot" field in the rio.cf file.
1240*/
1241int
1242RIOBootOk(p, HostP, RtaUniq)
1243struct rio_info * p;
1244struct Host * HostP;
1245ulong RtaUniq;
1246{
1247 int Entry;
1248 uint HostUniq = HostP->UniqueNum;
1249
1250 /*
1251 ** Search bindings table for RTA or its parent.
1252 ** If it exists, return 0, else 1.
1253 */
1254 for (Entry = 0;
1255 ( Entry < MAX_RTA_BINDINGS ) && ( p->RIOBindTab[Entry] != 0 );
1256 Entry++)
1257 {
1258 if ( (p->RIOBindTab[Entry] == HostUniq) ||
1259 (p->RIOBindTab[Entry] == RtaUniq) )
1260 return 0;
1261 }
1262 return 1;
1263}
1264
1265/*
1266** Make an empty slot tentative. If this is a 16 port RTA, make both
1267** slots tentative, and the second one RTA_SECOND_SLOT as well.
1268*/
1269
1270void
1271FillSlot(entry, entry2, RtaUniq, HostP)
1272int entry;
1273int entry2;
1274uint RtaUniq;
1275struct Host *HostP;
1276{
1277 int link;
1278
1279 rio_dprintk (RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq);
1280
1281 HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE);
1282 HostP->Mapping[entry].SysPort = NO_PORT;
1283 HostP->Mapping[entry].RtaUniqueNum = RtaUniq;
1284 HostP->Mapping[entry].HostUniqueNum = HostP->UniqueNum;
1285 HostP->Mapping[entry].ID = entry + 1;
1286 HostP->Mapping[entry].ID2 = 0;
1287 if (entry2) {
1288 HostP->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT |
1289 SLOT_TENTATIVE | RTA16_SECOND_SLOT);
1290 HostP->Mapping[entry2].SysPort = NO_PORT;
1291 HostP->Mapping[entry2].RtaUniqueNum = RtaUniq;
1292 HostP->Mapping[entry2].HostUniqueNum = HostP->UniqueNum;
1293 HostP->Mapping[entry2].Name[0] = '\0';
1294 HostP->Mapping[entry2].ID = entry2 + 1;
1295 HostP->Mapping[entry2].ID2 = entry + 1;
1296 HostP->Mapping[entry].ID2 = entry2 + 1;
1297 }
1298 /*
1299 ** Must set these up, so that utilities show
1300 ** topology of 16 port RTAs correctly
1301 */
1302 for ( link=0; link<LINKS_PER_UNIT; link++ ) {
1303 HostP->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT;
1304 HostP->Mapping[entry].Topology[link].Link = NO_LINK;
1305 if (entry2) {
1306 HostP->Mapping[entry2].Topology[link].Unit = ROUTE_DISCONNECT;
1307 HostP->Mapping[entry2].Topology[link].Link = NO_LINK;
1308 }
1309 }
1310}
1311
1312#if 0
1313/*
1314 Function: This function is to disable the disk interrupt
1315 Returns : Nothing
1316*/
1317void
1318disable_interrupt(vector)
1319int vector;
1320{
1321 int ps;
1322 int val;
1323
1324 disable(ps);
1325 if (vector > 40) {
1326 val = 1 << (vector - 40);
1327 __outb(S8259+1, __inb(S8259+1) | val);
1328 }
1329 else {
1330 val = 1 << (vector - 32);
1331 __outb(M8259+1, __inb(M8259+1) | val);
1332 }
1333 restore(ps);
1334}
1335
1336/*
1337 Function: This function is to enable the disk interrupt
1338 Returns : Nothing
1339*/
1340void
1341enable_interrupt(vector)
1342int vector;
1343{
1344 int ps;
1345 int val;
1346
1347 disable(ps);
1348 if (vector > 40) {
1349 val = 1 << (vector - 40);
1350 val = ~val;
1351 __outb(S8259+1, __inb(S8259+1) & val);
1352 }
1353 else {
1354 val = 1 << (vector - 32);
1355 val = ~val;
1356 __outb(M8259+1, __inb(M8259+1) & val);
1357 }
1358 restore(ps);
1359}
1360#endif
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
new file mode 100644
index 000000000000..533085ec6f1b
--- /dev/null
+++ b/drivers/char/rio/riocmd.c
@@ -0,0 +1,1041 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** ported from the existing SCO driver source
6**
7 *
8 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23**
24** Module : riocmd.c
25** SID : 1.2
26** Last Modified : 11/6/98 10:33:41
27** Retrieved : 11/6/98 10:33:49
28**
29** ident @(#)riocmd.c 1.2
30**
31** -----------------------------------------------------------------------------
32*/
33#ifdef SCCS_LABELS
34static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2";
35#endif
36
37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <linux/tty.h>
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/string.h>
44#include <asm/semaphore.h>
45
46#include <linux/termios.h>
47#include <linux/serial.h>
48
49#include <linux/generic_serial.h>
50
51#include "linux_compat.h"
52#include "rio_linux.h"
53#include "typdef.h"
54#include "pkt.h"
55#include "daemon.h"
56#include "rio.h"
57#include "riospace.h"
58#include "top.h"
59#include "cmdpkt.h"
60#include "map.h"
61#include "riotypes.h"
62#include "rup.h"
63#include "port.h"
64#include "riodrvr.h"
65#include "rioinfo.h"
66#include "func.h"
67#include "errors.h"
68#include "pci.h"
69
70#include "parmmap.h"
71#include "unixrup.h"
72#include "board.h"
73#include "host.h"
74#include "error.h"
75#include "phb.h"
76#include "link.h"
77#include "cmdblk.h"
78#include "route.h"
79#include "control.h"
80#include "cirrus.h"
81
82
83static struct IdentifyRta IdRta;
84static struct KillNeighbour KillUnit;
85
86int
87RIOFoadRta(struct Host *HostP, struct Map *MapP)
88{
89 struct CmdBlk *CmdBlkP;
90
91 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n");
92
93 CmdBlkP = RIOGetCmdBlk();
94
95 if ( !CmdBlkP ) {
96 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
97 return -ENXIO;
98 }
99
100 CmdBlkP->Packet.dest_unit = MapP->ID;
101 CmdBlkP->Packet.dest_port = BOOT_RUP;
102 CmdBlkP->Packet.src_unit = 0;
103 CmdBlkP->Packet.src_port = BOOT_RUP;
104 CmdBlkP->Packet.len = 0x84;
105 CmdBlkP->Packet.data[0] = IFOAD;
106 CmdBlkP->Packet.data[1] = 0;
107 CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF;
108 CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF;
109
110 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
111 rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
112 return -EIO;
113 }
114 return 0;
115}
116
117int
118RIOZombieRta(struct Host *HostP, struct Map *MapP)
119{
120 struct CmdBlk *CmdBlkP;
121
122 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n");
123
124 CmdBlkP = RIOGetCmdBlk();
125
126 if ( !CmdBlkP ) {
127 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
128 return -ENXIO;
129 }
130
131 CmdBlkP->Packet.dest_unit = MapP->ID;
132 CmdBlkP->Packet.dest_port = BOOT_RUP;
133 CmdBlkP->Packet.src_unit = 0;
134 CmdBlkP->Packet.src_port = BOOT_RUP;
135 CmdBlkP->Packet.len = 0x84;
136 CmdBlkP->Packet.data[0] = ZOMBIE;
137 CmdBlkP->Packet.data[1] = 0;
138 CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF;
139 CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF;
140
141 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
142 rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
143 return -EIO;
144 }
145 return 0;
146}
147
148int
149RIOCommandRta(struct rio_info *p, uint RtaUnique,
150 int (* func)(struct Host *HostP, struct Map *MapP))
151{
152 uint Host;
153
154 rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func);
155
156 if ( !RtaUnique )
157 return(0);
158
159 for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
160 uint Rta;
161 struct Host *HostP = &p->RIOHosts[Host];
162
163 for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
164 struct Map *MapP = &HostP->Mapping[Rta];
165
166 if ( MapP->RtaUniqueNum == RtaUnique ) {
167 uint Link;
168
169 /*
170 ** now, lets just check we have a route to it...
171 ** IF the routing stuff is working, then one of the
172 ** topology entries for this unit will have a legit
173 ** route *somewhere*. We care not where - if its got
174 ** any connections, we can get to it.
175 */
176 for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
177 if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
178 /*
179 ** Its worth trying the operation...
180 */
181 return (*func)( HostP, MapP );
182 }
183 }
184 }
185 }
186 }
187 return -ENXIO;
188}
189
190
191int
192RIOIdentifyRta(struct rio_info *p, caddr_t arg)
193{
194 uint Host;
195
196 if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
197 rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
198 p->RIOError.Error = COPYIN_FAILED;
199 return -EFAULT;
200 }
201
202 for ( Host = 0 ; Host < p->RIONumHosts; Host++ ) {
203 uint Rta;
204 struct Host *HostP = &p->RIOHosts[Host];
205
206 for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
207 struct Map *MapP = &HostP->Mapping[Rta];
208
209 if ( MapP->RtaUniqueNum == IdRta.RtaUnique ) {
210 uint Link;
211 /*
212 ** now, lets just check we have a route to it...
213 ** IF the routing stuff is working, then one of the
214 ** topology entries for this unit will have a legit
215 ** route *somewhere*. We care not where - if its got
216 ** any connections, we can get to it.
217 */
218 for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
219 if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
220 /*
221 ** Its worth trying the operation...
222 */
223 struct CmdBlk *CmdBlkP;
224
225 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n");
226
227 CmdBlkP = RIOGetCmdBlk();
228
229 if ( !CmdBlkP ) {
230 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
231 return -ENXIO;
232 }
233
234 CmdBlkP->Packet.dest_unit = MapP->ID;
235 CmdBlkP->Packet.dest_port = BOOT_RUP;
236 CmdBlkP->Packet.src_unit = 0;
237 CmdBlkP->Packet.src_port = BOOT_RUP;
238 CmdBlkP->Packet.len = 0x84;
239 CmdBlkP->Packet.data[0] = IDENTIFY;
240 CmdBlkP->Packet.data[1] = 0;
241 CmdBlkP->Packet.data[2] = IdRta.ID;
242
243 if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
244 rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
245 return -EIO;
246 }
247 return 0;
248 }
249 }
250 }
251 }
252 }
253 return -ENOENT;
254}
255
256
257int
258RIOKillNeighbour(struct rio_info *p, caddr_t arg)
259{
260 uint Host;
261 uint ID;
262 struct Host *HostP;
263 struct CmdBlk *CmdBlkP;
264
265 rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");
266
267 if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
268 rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
269 p->RIOError.Error = COPYIN_FAILED;
270 return -EFAULT;
271 }
272
273 if ( KillUnit.Link > 3 )
274 return -ENXIO;
275
276 CmdBlkP = RIOGetCmdBlk();
277
278 if ( !CmdBlkP ) {
279 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
280 return -ENXIO;
281 }
282
283 CmdBlkP->Packet.dest_unit = 0;
284 CmdBlkP->Packet.src_unit = 0;
285 CmdBlkP->Packet.dest_port = BOOT_RUP;
286 CmdBlkP->Packet.src_port = BOOT_RUP;
287 CmdBlkP->Packet.len = 0x84;
288 CmdBlkP->Packet.data[0] = UFOAD;
289 CmdBlkP->Packet.data[1] = KillUnit.Link;
290 CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF;
291 CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF;
292
293 for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
294 ID = 0;
295 HostP = &p->RIOHosts[Host];
296
297 if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
298 if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
299 CmdBlkP) == RIO_FAIL ) {
300 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
301 return -EIO;
302 }
303 return 0;
304 }
305
306 for ( ID=0; ID < RTAS_PER_HOST; ID++ ) {
307 if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
308 CmdBlkP->Packet.dest_unit = ID+1;
309 if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
310 rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
311 return -EIO;
312 }
313 return 0;
314 }
315 }
316 }
317 RIOFreeCmdBlk( CmdBlkP );
318 return -ENXIO;
319}
320
321int
322RIOSuspendBootRta(struct Host *HostP, int ID, int Link)
323{
324 struct CmdBlk *CmdBlkP;
325
326 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);
327
328 CmdBlkP = RIOGetCmdBlk();
329
330 if ( !CmdBlkP ) {
331 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
332 return -ENXIO;
333 }
334
335 CmdBlkP->Packet.dest_unit = ID;
336 CmdBlkP->Packet.dest_port = BOOT_RUP;
337 CmdBlkP->Packet.src_unit = 0;
338 CmdBlkP->Packet.src_port = BOOT_RUP;
339 CmdBlkP->Packet.len = 0x84;
340 CmdBlkP->Packet.data[0] = IWAIT;
341 CmdBlkP->Packet.data[1] = Link;
342 CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF;
343 CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF;
344
345 if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
346 rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
347 return -EIO;
348 }
349 return 0;
350}
351
352int
353RIOFoadWakeup(struct rio_info *p)
354{
355 int port;
356 register struct Port *PortP;
357 unsigned long flags;
358
359 for ( port=0; port<RIO_PORTS; port++) {
360 PortP = p->RIOPortp[port];
361
362 rio_spin_lock_irqsave(&PortP->portSem, flags);
363 PortP->Config = 0;
364 PortP->State = 0;
365 PortP->InUse = NOT_INUSE;
366 PortP->PortState = 0;
367 PortP->FlushCmdBodge = 0;
368 PortP->ModemLines = 0;
369 PortP->ModemState = 0;
370 PortP->CookMode = 0;
371 PortP->ParamSem = 0;
372 PortP->Mapped = 0;
373 PortP->WflushFlag = 0;
374 PortP->MagicFlags = 0;
375 PortP->RxDataStart = 0;
376 PortP->TxBufferIn = 0;
377 PortP->TxBufferOut = 0;
378 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
379 }
380 return(0);
381}
382
383/*
384** Incoming command on the COMMAND_RUP to be processed.
385*/
386static int
387RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP)
388{
389 struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
390 struct Port *PortP;
391 struct UnixRup *UnixRupP;
392 ushort SysPort;
393 ushort ReportedModemStatus;
394 ushort rup;
395 ushort subCommand;
396 unsigned long flags;
397
398 func_enter ();
399
400#ifdef CHECK
401 CheckHost( Host );
402 CheckHostP( HostP );
403 CheckPacketP( PacketP );
404#endif
405
406 /*
407 ** 16 port RTA note:
408 ** Command rup packets coming from the RTA will have pkt->data[1] (which
409 ** translates to PktCmdP->PhbNum) set to the host port number for the
410 ** particular unit. To access the correct BaseSysPort for a 16 port RTA,
411 ** we can use PhbNum to get the rup number for the appropriate 8 port
412 ** block (for the first block, this should be equal to 'Rup').
413 */
414 rup = RBYTE(PktCmdP->PhbNum) / (ushort)PORTS_PER_RTA;
415 UnixRupP = &HostP->UnixRups[rup];
416 SysPort = UnixRupP->BaseSysPort +
417 (RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
418 rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);
419
420#ifdef CHECK
421 CheckRup( rup );
422 CheckUnixRupP( UnixRupP );
423#endif
424 if ( UnixRupP->BaseSysPort == NO_PORT ) {
425 rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
426 rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
427 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n",
428 HostP-p->RIOHosts, HostP->Name );
429 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup);
430
431 if ( Rup >= (ushort)MAX_RUP ) {
432 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",
433 HostP->Mapping[Rup].Name);
434 } else
435 rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n",
436 ('A' + Rup - MAX_RUP), HostP->Name);
437
438 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",
439 PacketP->dest_unit, PacketP->dest_port );
440 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n",
441 PacketP->src_unit, PacketP->src_port );
442 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", PacketP->len,PacketP->len );
443 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", PacketP->control, PacketP->control);
444 rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", PacketP->csum, PacketP->csum );
445 rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, "
446 "Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );
447 return TRUE;
448 }
449
450#ifdef CHECK
451 CheckSysPort( SysPort );
452#endif
453 PortP = p->RIOPortp[ SysPort ];
454 rio_spin_lock_irqsave(&PortP->portSem, flags);
455 switch( RBYTE(PktCmdP->Command) ) {
456 case BREAK_RECEIVED:
457 rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");
458 /* If the current line disc. is not multi-threading and
459 the current processor is not the default, reset rup_intr
460 and return FALSE to ensure that the command packet is
461 not freed. */
462 /* Call tmgr HANGUP HERE */
463 /* Fix this later when every thing works !!!! RAMRAJ */
464 gs_got_break (&PortP->gs);
465 break;
466
467 case COMPLETE:
468 rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",
469 RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
470 subCommand = 1;
471 switch (RBYTE(PktCmdP->SubCommand)) {
472 case MEMDUMP :
473 rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",
474 RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
475 break;
476 case READ_REGISTER :
477 rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));
478 p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
479 break;
480 default :
481 subCommand = 0;
482 break;
483 }
484 if (subCommand)
485 break;
486 rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",
487 RBYTE(PktCmdP->PortStatus),PortP->PortState);
488 if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
489 rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");
490 PortP->PortState = RBYTE(PktCmdP->PortStatus);
491 /* What should we do here ...
492 wakeup( &PortP->PortState );
493 */
494 } else
495 rio_dprintk (RIO_DEBUG_CMD, "No change\n");
496
497 /* FALLTHROUGH */
498 case MODEM_STATUS:
499 /*
500 ** Knock out the tbusy and tstop bits, as these are not relevant
501 ** to the check for modem status change (they're just there because
502 ** it's a convenient place to put them!).
503 */
504 ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
505 if ((PortP->ModemState & MSVR1_HOST) ==
506 (ReportedModemStatus & MSVR1_HOST)) {
507 rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
508 /*
509 ** Update ModemState just in case tbusy or tstop states have
510 ** changed.
511 */
512 PortP->ModemState = ReportedModemStatus;
513 }
514 else {
515 rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",
516 PortP->ModemState, ReportedModemStatus);
517 PortP->ModemState = ReportedModemStatus;
518#ifdef MODEM_SUPPORT
519 if ( PortP->Mapped ) {
520 /***********************************************************\
521 *************************************************************
522 *** ***
523 *** M O D E M S T A T E C H A N G E ***
524 *** ***
525 *************************************************************
526 \***********************************************************/
527 /*
528 ** If the device is a modem, then check the modem
529 ** carrier.
530 */
531 if (PortP->gs.tty == NULL)
532 break;
533 if (PortP->gs.tty->termios == NULL)
534 break;
535
536 if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
537 ((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
538
539 rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");
540 /*
541 ** Is there a carrier?
542 */
543 if ( PortP->ModemState & MSVR1_CD ) {
544 /*
545 ** Has carrier just appeared?
546 */
547 if (!(PortP->State & RIO_CARR_ON)) {
548 rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");
549 PortP->State |= RIO_CARR_ON;
550 /*
551 ** wakeup anyone in WOPEN
552 */
553 if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
554 wake_up_interruptible (&PortP->gs.open_wait);
555#ifdef STATS
556 PortP->Stat.ModemOnCnt++;
557#endif
558 }
559 } else {
560 /*
561 ** Has carrier just dropped?
562 */
563 if (PortP->State & RIO_CARR_ON) {
564 if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
565 tty_hangup (PortP->gs.tty);
566 PortP->State &= ~RIO_CARR_ON;
567 rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");
568#ifdef STATS
569 PortP->Stat.ModemOffCnt++;
570#endif
571 }
572 }
573 }
574 }
575#endif
576 }
577 break;
578
579 default:
580 rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",
581 RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
582 break;
583 }
584 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
585
586 func_exit ();
587
588 return TRUE;
589}
590/*
591** The command mechanism:
592** Each rup has a chain of commands associated with it.
593** This chain is maintained by routines in this file.
594** Periodically we are called and we run a quick check of all the
595** active chains to determine if there is a command to be executed,
596** and if the rup is ready to accept it.
597**
598*/
599
600/*
601** Allocate an empty command block.
602*/
603struct CmdBlk *
604RIOGetCmdBlk(void)
605{
606 struct CmdBlk *CmdBlkP;
607
608 CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk));
609 if (CmdBlkP)
610 bzero(CmdBlkP, sizeof(struct CmdBlk));
611
612 return CmdBlkP;
613}
614
615/*
616** Return a block to the head of the free list.
617*/
618void
619RIOFreeCmdBlk(struct CmdBlk *CmdBlkP)
620{
621 sysfree((void *)CmdBlkP, sizeof(struct CmdBlk));
622}
623
624/*
625** attach a command block to the list of commands to be performed for
626** a given rup.
627*/
628int
629RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP)
630{
631 struct CmdBlk **Base;
632 struct UnixRup *UnixRupP;
633 unsigned long flags;
634
635#ifdef CHECK
636 CheckHostP( HostP );
637 CheckRup( Rup );
638 CheckCmdBlkP( CmdBlkP );
639#endif
640 if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
641 rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);
642 RIOFreeCmdBlk( CmdBlkP );
643 return RIO_FAIL;
644 }
645
646 UnixRupP = &HostP->UnixRups[Rup];
647
648 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
649
650 /*
651 ** If the RUP is currently inactive, then put the request
652 ** straight on the RUP....
653 */
654 if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) &&
655 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
656 (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
657 :TRUE)) {
658 rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
659 CmdBlkP->Packet.data[0]);
660
661 /*
662 ** Whammy! blat that pack!
663 */
664 HostP->Copy( (caddr_t)&CmdBlkP->Packet,
665 RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt ), sizeof(PKT) );
666
667 /*
668 ** place command packet on the pending position.
669 */
670 UnixRupP->CmdPendingP = CmdBlkP;
671
672 /*
673 ** set the command register
674 */
675 WWORD(UnixRupP->RupP->txcontrol , TX_PACKET_READY);
676
677 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
678
679 return RIO_SUCCESS;
680 }
681 rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");
682
683 if ( UnixRupP->CmdsWaitingP != NULL)
684 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");
685 if ( UnixRupP->CmdPendingP != NULL )
686 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");
687 if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
688 rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");
689
690 Base = &UnixRupP->CmdsWaitingP;
691
692 rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);
693
694 while ( *Base ) {
695 rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));
696 Base = &((*Base)->NextP);
697 rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n",
698 (int)CmdBlkP,(int)Base);
699 }
700
701 rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base);
702
703 *Base = CmdBlkP;
704
705 CmdBlkP->NextP = NULL;
706
707 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
708
709 return RIO_SUCCESS;
710}
711
712/*
713** Here we go - if there is an empty rup, fill it!
714** must be called at splrio() or higher.
715*/
716void
717RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
718{
719 register struct CmdBlk *CmdBlkP;
720 register struct UnixRup *UnixRupP;
721 struct PKT *PacketP;
722 ushort Rup;
723 unsigned long flags;
724
725
726 Rup = MAX_RUP+LINKS_PER_UNIT;
727
728 do { /* do this loop for each RUP */
729 /*
730 ** locate the rup we are processing & lock it
731 */
732 UnixRupP = &HostP->UnixRups[--Rup];
733
734 spin_lock_irqsave(&UnixRupP->RupLock, flags);
735
736 /*
737 ** First check for incoming commands:
738 */
739 if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
740 int FreeMe;
741
742 PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));
743
744 ShowPacket( DBG_CMD, PacketP );
745
746 switch ( RBYTE(PacketP->dest_port) ) {
747 case BOOT_RUP:
748 rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n",
749 RBYTE(PacketP->len) & 0x80 ? "Command":"Data",
750 RBYTE(PacketP->data[0]));
751 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
752 FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
753 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
754 break;
755
756 case COMMAND_RUP:
757 /*
758 ** Free the RUP lock as loss of carrier causes a
759 ** ttyflush which will (eventually) call another
760 ** routine that uses the RUP lock.
761 */
762 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
763 FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
764 if (PacketP->data[5] == MEMDUMP) {
765 rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
766 *(ushort *) &(PacketP->data[6]));
767 HostP->Copy( (caddr_t)&(PacketP->data[8]),
768 (caddr_t)p->RIOMemDump, 32 );
769 }
770 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
771 break;
772
773 case ROUTE_RUP:
774 rio_spin_unlock_irqrestore( &UnixRupP->RupLock, flags);
775 FreeMe = RIORouteRup(p, Rup, HostP, PacketP );
776 rio_spin_lock_irqsave( &UnixRupP->RupLock, flags );
777 break;
778
779 default:
780 rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port));
781 FreeMe = 1;
782 break;
783 }
784
785 if ( FreeMe ) {
786 rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n");
787 put_free_end(HostP,PacketP);
788
789 WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);
790
791 if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
792 rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup);
793 WWORD(UnixRupP->RupP->handshake,
794 PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
795 }
796 }
797 }
798
799 /*
800 ** IF a command was running on the port,
801 ** and it has completed, then tidy it up.
802 */
803 if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
804 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
805 /*
806 ** we are idle.
807 ** there is a command in pending.
808 ** Therefore, this command has finished.
809 ** So, wakeup whoever is waiting for it (and tell them
810 ** what happened).
811 */
812 if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
813 rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n",
814 CmdBlkP->Packet.len & 0x80 ? "Command":"Data",
815 CmdBlkP->Packet.data[0]);
816
817 rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP);
818
819 /*
820 ** Clear the Rup lock to prevent mutual exclusion.
821 */
822 if ( CmdBlkP->PostFuncP ) {
823 rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
824 (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg,CmdBlkP);
825 rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
826 }
827
828 /*
829 ** ....clear the pending flag....
830 */
831 UnixRupP->CmdPendingP = NULL;
832
833 /*
834 ** ....and return the command block to the freelist.
835 */
836 RIOFreeCmdBlk( CmdBlkP );
837 }
838
839 /*
840 ** If there is a command for this rup, and the rup
841 ** is idle, then process the command
842 */
843 if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
844 (UnixRupP->CmdPendingP == NULL) &&
845 (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
846 /*
847 ** if the pre-function is non-zero, call it.
848 ** If it returns RIO_FAIL then don't
849 ** send this command yet!
850 */
851#ifdef CHECK
852 CheckCmdBlkP (CmdBlkP);
853#endif
854 if ( !(CmdBlkP->PreFuncP ?
855 (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
856 rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP);
857 }
858 else {
859 rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n",
860 (int)CmdBlkP, CmdBlkP->Packet.data[0]);
861 /*
862 ** Whammy! blat that pack!
863 */
864#ifdef CHECK
865 CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
866#endif
867 HostP->Copy( (caddr_t)&CmdBlkP->Packet,
868 RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));
869
870 /*
871 ** remove the command from the rup command queue...
872 */
873 UnixRupP->CmdsWaitingP = CmdBlkP->NextP;
874
875 /*
876 ** ...and place it on the pending position.
877 */
878 UnixRupP->CmdPendingP = CmdBlkP;
879
880 /*
881 ** set the command register
882 */
883 WWORD(UnixRupP->RupP->txcontrol,TX_PACKET_READY);
884
885 /*
886 ** the command block will be freed
887 ** when the command has been processed.
888 */
889 }
890 }
891 spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
892 } while ( Rup );
893}
894
895int
896RIOWFlushMark(int iPortP, struct CmdBlk *CmdBlkP)
897{
898 struct Port * PortP = (struct Port *)iPortP;
899 unsigned long flags;
900
901 rio_spin_lock_irqsave(&PortP->portSem, flags);
902#ifdef CHECK
903 CheckPortP( PortP );
904#endif
905 PortP->WflushFlag++;
906 PortP->MagicFlags |= MAGIC_FLUSH;
907 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
908 return RIOUnUse( iPortP, CmdBlkP );
909}
910
911int
912RIORFlushEnable(int iPortP, struct CmdBlk *CmdBlkP)
913{
914 struct Port * PortP = (struct Port *)iPortP;
915 PKT *PacketP;
916 unsigned long flags;
917
918 rio_spin_lock_irqsave(&PortP->portSem, flags);
919
920 while ( can_remove_receive(&PacketP, PortP) ) {
921 remove_receive(PortP);
922 ShowPacket(DBG_PROC, PacketP );
923 put_free_end( PortP->HostP, PacketP );
924 }
925
926 if ( RWORD(PortP->PhbP->handshake)==PHB_HANDSHAKE_SET ) {
927 /*
928 ** MAGIC! (Basically, handshake the RX buffer, so that
929 ** the RTAs upstream can be re-enabled.)
930 */
931 rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
932 WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
933 }
934 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
935 return RIOUnUse( iPortP, CmdBlkP );
936}
937
938int
939RIOUnUse(int iPortP, struct CmdBlk *CmdBlkP)
940{
941 struct Port * PortP = (struct Port *)iPortP;
942 unsigned long flags;
943
944 rio_spin_lock_irqsave(&PortP->portSem, flags);
945
946#ifdef CHECK
947 CheckPortP( PortP );
948#endif
949 rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n");
950
951 if (PortP->InUse) {
952 if ( --PortP->InUse != NOT_INUSE ) {
953 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
954 return 0;
955 }
956 }
957 /*
958 ** While PortP->InUse is set (i.e. a preemptive command has been sent to
959 ** the RTA and is awaiting completion), any transmit data is prevented from
960 ** being transferred from the write queue into the transmit packets
961 ** (add_transmit) and no furthur transmit interrupt will be sent for that
962 ** data. The next interrupt will occur up to 500ms later (RIOIntr is called
963 ** twice a second as a saftey measure). This was the case when kermit was
964 ** used to send data into a RIO port. After each packet was sent, TCFLSH
965 ** was called to flush the read queue preemptively. PortP->InUse was
966 ** incremented, thereby blocking the 6 byte acknowledgement packet
967 ** transmitted back. This acknowledgment hung around for 500ms before
968 ** being sent, thus reducing input performance substantially!.
969 ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data
970 ** hanging around in the transmit buffer is sent immediately.
971 */
972 WWORD(PortP->HostP->ParmMapP->tx_intr, 1);
973 /* What to do here ..
974 wakeup( (caddr_t)&(PortP->InUse) );
975 */
976 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
977 return 0;
978}
979
980void
981ShowPacket(uint Flags, struct PKT *PacketP)
982{
983}
984
985/*
986**
987** How to use this file:
988**
989** To send a command down a rup, you need to allocate a command block, fill
990** in the packet information, fill in the command number, fill in the pre-
991** and post- functions and arguments, and then add the command block to the
992** queue of command blocks for the port in question. When the port is idle,
993** then the pre-function will be called. If this returns RIO_FAIL then the
994** command will be re-queued and tried again at a later date (probably in one
995** clock tick). If the pre-function returns NOT RIO_FAIL, then the command
996** packet will be queued on the RUP, and the txcontrol field set to the
997** command number. When the txcontrol field has changed from being the
998** command number, then the post-function will be called, with the argument
999** specified earlier, a pointer to the command block, and the value of
1000** txcontrol.
1001**
1002** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer
1003** to the command block structure allocated, or NULL if there aren't any.
1004** The block will have been zeroed for you.
1005**
1006** The structure has the following fields:
1007**
1008** struct CmdBlk
1009** {
1010** struct CmdBlk *NextP; ** Pointer to next command block **
1011** struct PKT Packet; ** A packet, to copy to the rup **
1012** int (*PreFuncP)(); ** The func to call to check if OK **
1013** int PreArg; ** The arg for the func **
1014** int (*PostFuncP)(); ** The func to call when completed **
1015** int PostArg; ** The arg for the func **
1016** };
1017**
1018** You need to fill in ALL fields EXCEPT NextP, which is used to link the
1019** blocks together either on the free list or on the Rup list.
1020**
1021** Packet is an actual packet structure to be filled in with the packet
1022** information associated with the command. You need to fill in everything,
1023** as the command processore doesn't process the command packet in any way.
1024**
1025** The PreFuncP is called before the packet is enqueued on the host rup.
1026** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must
1027** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL
1028** if the packet is NOT to be queued.
1029**
1030** The PostFuncP is called when the command has completed. It is called
1031** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected
1032** to return a value. PostFuncP does NOT need to free the command block,
1033** as this happens automatically after PostFuncP returns.
1034**
1035** Once the command block has been filled in, it is attached to the correct
1036** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is
1037** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer
1038** to it!), and CmdBlkP is the pointer to the command block allocated using
1039** RIOGetCmdBlk().
1040**
1041*/
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
new file mode 100644
index 000000000000..b4d1a23e27e4
--- /dev/null
+++ b/drivers/char/rio/rioctrl.c
@@ -0,0 +1,1869 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rioctrl.c
24** SID : 1.3
25** Last Modified : 11/6/98 10:33:42
26** Retrieved : 11/6/98 10:33:49
27**
28** ident @(#)rioctrl.c 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32#ifdef SCCS_LABELS
33static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3";
34#endif
35
36
37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <asm/io.h>
41#include <asm/system.h>
42#include <asm/string.h>
43#include <asm/semaphore.h>
44#include <asm/uaccess.h>
45
46#include <linux/termios.h>
47#include <linux/serial.h>
48
49#include <linux/generic_serial.h>
50
51
52#include "linux_compat.h"
53#include "rio_linux.h"
54#include "typdef.h"
55#include "pkt.h"
56#include "daemon.h"
57#include "rio.h"
58#include "riospace.h"
59#include "top.h"
60#include "cmdpkt.h"
61#include "map.h"
62#include "riotypes.h"
63#include "rup.h"
64#include "port.h"
65#include "riodrvr.h"
66#include "rioinfo.h"
67#include "func.h"
68#include "errors.h"
69#include "pci.h"
70
71#include "parmmap.h"
72#include "unixrup.h"
73#include "board.h"
74#include "host.h"
75#include "error.h"
76#include "phb.h"
77#include "link.h"
78#include "cmdblk.h"
79#include "route.h"
80#include "control.h"
81#include "cirrus.h"
82#include "rioioctl.h"
83
84
85static struct LpbReq LpbReq;
86static struct RupReq RupReq;
87static struct PortReq PortReq;
88static struct HostReq HostReq;
89static struct HostDpRam HostDpRam;
90static struct DebugCtrl DebugCtrl;
91static struct Map MapEnt;
92static struct PortSetup PortSetup;
93static struct DownLoad DownLoad;
94static struct SendPack SendPack;
95/* static struct StreamInfo StreamInfo; */
96/* static char modemtable[RIO_PORTS]; */
97static struct SpecialRupCmd SpecialRupCmd;
98static struct PortParams PortParams;
99static struct portStats portStats;
100
101static struct SubCmdStruct {
102 ushort Host;
103 ushort Rup;
104 ushort Port;
105 ushort Addr;
106} SubCmd;
107
108struct PortTty {
109 uint port;
110 struct ttystatics Tty;
111};
112
113static struct PortTty PortTty;
114typedef struct ttystatics TERMIO;
115
116/*
117** This table is used when the config.rio downloads bin code to the
118** driver. We index the table using the product code, 0-F, and call
119** the function pointed to by the entry, passing the information
120** about the boot.
121** The RIOBootCodeUNKNOWN entry is there to politely tell the calling
122** process to bog off.
123*/
124static int
125(*RIOBootTable[MAX_PRODUCT])(struct rio_info *, struct DownLoad *) =
126{
127/* 0 */ RIOBootCodeHOST, /* Host Card */
128/* 1 */ RIOBootCodeRTA, /* RTA */
129};
130
131#define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff))
132
133int copyin (int arg, caddr_t dp, int siz)
134{
135 int rv;
136
137 rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes from user %p to %p.\n", siz, (void *)arg, dp);
138 rv = copy_from_user (dp, (void *)arg, siz);
139 if (rv) return COPYFAIL;
140 else return rv;
141}
142
143static int copyout (caddr_t dp, int arg, int siz)
144{
145 int rv;
146
147 rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes to user %p from %p.\n", siz, (void *)arg, dp);
148 rv = copy_to_user ((void *)arg, dp, siz);
149 if (rv) return COPYFAIL;
150 else return rv;
151}
152
153int
154riocontrol(p, dev, cmd, arg, su)
155struct rio_info * p;
156dev_t dev;
157int cmd;
158caddr_t arg;
159int su;
160{
161 uint Host; /* leave me unsigned! */
162 uint port; /* and me! */
163 struct Host *HostP;
164 ushort loop;
165 int Entry;
166 struct Port *PortP;
167 PKT *PacketP;
168 int retval = 0;
169 unsigned long flags;
170
171 func_enter ();
172
173 /* Confuse the compiler to think that we've initialized these */
174 Host=0;
175 PortP = NULL;
176
177 rio_dprintk (RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg);
178
179 switch (cmd) {
180 /*
181 ** RIO_SET_TIMER
182 **
183 ** Change the value of the host card interrupt timer.
184 ** If the host card number is -1 then all host cards are changed
185 ** otherwise just the specified host card will be changed.
186 */
187 case RIO_SET_TIMER:
188 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_TIMER to %dms\n", (uint)arg);
189 {
190 int host, value;
191 host = (uint)arg >> 16;
192 value = (uint)arg & 0x0000ffff;
193 if (host == -1) {
194 for (host = 0; host < p->RIONumHosts; host++) {
195 if (p->RIOHosts[host].Flags == RC_RUNNING) {
196 WWORD(p->RIOHosts[host].ParmMapP->timer , value);
197 }
198 }
199 } else if (host >= p->RIONumHosts) {
200 return -EINVAL;
201 } else {
202 if ( p->RIOHosts[host].Flags == RC_RUNNING ) {
203 WWORD(p->RIOHosts[host].ParmMapP->timer , value);
204 }
205 }
206 }
207 return 0;
208
209 case RIO_IDENTIFY_DRIVER:
210 /*
211 ** 15.10.1998 ARG - ESIL 0760 part fix
212 ** Added driver ident string output.
213 **
214#ifndef __THIS_RELEASE__
215#warning Driver Version string not defined !
216#endif
217 cprintf("%s %s %s %s\n",
218 RIO_DRV_STR,
219 __THIS_RELEASE__,
220 __DATE__, __TIME__ );
221
222 return 0;
223
224 case RIO_DISPLAY_HOST_CFG:
225 **
226 ** 15.10.1998 ARG - ESIL 0760 part fix
227 ** Added driver host card ident string output.
228 **
229 ** Note that the only types currently supported
230 ** are ISA and PCI. Also this driver does not
231 ** (yet) distinguish between the Old PCI card
232 ** and the Jet PCI card. In fact I think this
233 ** driver only supports JET PCI !
234 **
235
236 for (Host = 0; Host < p->RIONumHosts; Host++)
237 {
238 HostP = &(p->RIOHosts[Host]);
239
240 switch ( HostP->Type )
241 {
242 case RIO_AT :
243 strcpy( host_type, RIO_AT_HOST_STR );
244 break;
245
246 case RIO_PCI :
247 strcpy( host_type, RIO_PCI_HOST_STR );
248 break;
249
250 default :
251 strcpy( host_type, "Unknown" );
252 break;
253 }
254
255 cprintf(
256 "RIO Host %d - Type:%s Addr:%X IRQ:%d\n",
257 Host, host_type,
258 (uint)HostP->PaddrP,
259 (int)HostP->Ivec - 32 );
260 }
261 return 0;
262 **
263 */
264
265 case RIO_FOAD_RTA:
266 rio_dprintk (RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n");
267 return RIOCommandRta(p, (uint)arg, RIOFoadRta);
268
269 case RIO_ZOMBIE_RTA:
270 rio_dprintk (RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n");
271 return RIOCommandRta(p, (uint)arg, RIOZombieRta);
272
273 case RIO_IDENTIFY_RTA:
274 rio_dprintk (RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n");
275 return RIOIdentifyRta(p, arg);
276
277 case RIO_KILL_NEIGHBOUR:
278 rio_dprintk (RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n");
279 return RIOKillNeighbour(p, arg);
280
281 case SPECIAL_RUP_CMD:
282 {
283 struct CmdBlk *CmdBlkP;
284
285 rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n");
286 if (copyin((int)arg, (caddr_t)&SpecialRupCmd,
287 sizeof(SpecialRupCmd)) == COPYFAIL ) {
288 rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n");
289 p->RIOError.Error = COPYIN_FAILED;
290 return -EFAULT;
291 }
292 CmdBlkP = RIOGetCmdBlk();
293 if ( !CmdBlkP ) {
294 rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n");
295 return -ENXIO;
296 }
297 CmdBlkP->Packet = SpecialRupCmd.Packet;
298 if ( SpecialRupCmd.Host >= p->RIONumHosts )
299 SpecialRupCmd.Host = 0;
300 rio_dprintk (RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n",
301 SpecialRupCmd.Host, SpecialRupCmd.RupNum);
302 if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host],
303 SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) {
304 cprintf("FAILED TO QUEUE SPECIAL RUP COMMAND\n");
305 }
306 return 0;
307 }
308
309 case RIO_DEBUG_MEM:
310#ifdef DEBUG_MEM_SUPPORT
311RIO_DEBUG_CTRL, if (su)
312 return rio_RIODebugMemory(RIO_DEBUG_CTRL, arg);
313 else
314#endif
315 return -EPERM;
316
317 case RIO_ALL_MODEM:
318 rio_dprintk (RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n");
319 p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
320 return -EINVAL;
321
322 case RIO_GET_TABLE:
323 /*
324 ** Read the routing table from the device driver to user space
325 */
326 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE\n");
327
328 if ((retval = RIOApel(p)) != 0)
329 return retval;
330
331 if (copyout((caddr_t)p->RIOConnectTable, (int)arg,
332 TOTAL_MAP_ENTRIES*sizeof(struct Map)) == COPYFAIL) {
333 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
334 p->RIOError.Error = COPYOUT_FAILED;
335 return -EFAULT;
336 }
337
338 {
339 int entry;
340 rio_dprintk (RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n");
341 for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
342 {
343 if ((p->RIOConnectTable[entry].ID == 0) &&
344 (p->RIOConnectTable[entry].HostUniqueNum == 0) &&
345 (p->RIOConnectTable[entry].RtaUniqueNum == 0)) continue;
346
347 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum );
348 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum );
349 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID );
350 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 );
351 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags );
352 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort );
353 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit );
354 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link );
355 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit );
356 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link );
357 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit );
358 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link );
359 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit );
360 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link );
361 rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name );
362 }
363 rio_dprintk (RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n");
364 }
365 p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */
366 return 0;
367
368 case RIO_PUT_TABLE:
369 /*
370 ** Write the routing table to the device driver from user space
371 */
372 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n");
373
374 if ( !su ) {
375 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n");
376 p->RIOError.Error = NOT_SUPER_USER;
377 return -EPERM;
378 }
379 if ( copyin((int)arg, (caddr_t)&p->RIOConnectTable[0],
380 TOTAL_MAP_ENTRIES*sizeof(struct Map) ) == COPYFAIL ) {
381 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
382 p->RIOError.Error = COPYIN_FAILED;
383 return -EFAULT;
384 }
385/*
386***********************************
387 {
388 int entry;
389 rio_dprint(RIO_DEBUG_CTRL, ("*****\nMAP ENTRIES\n") );
390 for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
391 {
392 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ) );
393 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) );
394 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) );
395 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) );
396 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Flags = 0x%x\n", entry, p->RIOConnectTable[entry].Flags ) );
397 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.SysPort = 0x%x\n", entry, p->RIOConnectTable[entry].SysPort ) );
398 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) );
399 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) );
400 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) );
401 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) );
402 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) );
403 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) );
404 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[3].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) );
405 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[4].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) );
406 rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) );
407 }
408 rio_dprint(RIO_DEBUG_CTRL, ("*****\nEND MAP ENTRIES\n") );
409 }
410***********************************
411*/
412 return RIONewTable(p);
413
414 case RIO_GET_BINDINGS :
415 /*
416 ** Send bindings table, containing unique numbers of RTAs owned
417 ** by this system to user space
418 */
419 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n");
420
421 if ( !su )
422 {
423 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n");
424 p->RIOError.Error = NOT_SUPER_USER;
425 return -EPERM;
426 }
427 if (copyout((caddr_t) p->RIOBindTab, (int)arg,
428 (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL ) {
429 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
430 p->RIOError.Error = COPYOUT_FAILED;
431 return -EFAULT;
432 }
433 return 0;
434
435 case RIO_PUT_BINDINGS :
436 /*
437 ** Receive a bindings table, containing unique numbers of RTAs owned
438 ** by this system
439 */
440 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n");
441
442 if ( !su )
443 {
444 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n");
445 p->RIOError.Error = NOT_SUPER_USER;
446 return -EPERM;
447 }
448 if (copyin((int)arg, (caddr_t)&p->RIOBindTab[0],
449 (sizeof(ulong) * MAX_RTA_BINDINGS))==COPYFAIL ) {
450 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
451 p->RIOError.Error = COPYIN_FAILED;
452 return -EFAULT;
453 }
454 return 0;
455
456 case RIO_BIND_RTA :
457 {
458 int EmptySlot = -1;
459 /*
460 ** Bind this RTA to host, so that it will be booted by
461 ** host in 'boot owned RTAs' mode.
462 */
463 rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA\n");
464
465 if ( !su ) {
466 rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n");
467 p->RIOError.Error = NOT_SUPER_USER;
468 return -EPERM;
469 }
470 for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) {
471 if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L))
472 EmptySlot = Entry;
473 else if (p->RIOBindTab[Entry] == (int) arg) {
474 /*
475 ** Already exists - delete
476 */
477 p->RIOBindTab[Entry] = 0L;
478 rio_dprintk (RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n",
479 (int) arg);
480 return 0;
481 }
482 }
483 /*
484 ** Dosen't exist - add
485 */
486 if (EmptySlot != -1) {
487 p->RIOBindTab[EmptySlot] = (int) arg;
488 rio_dprintk (RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n",
489 (int) arg);
490 }
491 else {
492 rio_dprintk (RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n",
493 (int) arg);
494 return -ENOMEM;
495 }
496 return 0;
497 }
498
499 case RIO_RESUME :
500 rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME\n");
501 port = (uint) arg;
502 if ((port < 0) || (port > 511)) {
503 rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
504 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
505 return -EINVAL;
506 }
507 PortP = p->RIOPortp[port];
508 if (!PortP->Mapped) {
509 rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port);
510 p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
511 return -EINVAL;
512 }
513 if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
514 rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port);
515 return -EINVAL;
516 }
517
518 rio_spin_lock_irqsave(&PortP->portSem, flags);
519 if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) ==
520 RIO_FAIL) {
521 rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME failed\n");
522 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
523 return -EBUSY;
524 }
525 else {
526 rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port);
527 PortP->State |= RIO_BUSY;
528 }
529 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
530 return retval;
531
532 case RIO_ASSIGN_RTA:
533 rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n");
534 if ( !su ) {
535 rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n");
536 p->RIOError.Error = NOT_SUPER_USER;
537 return -EPERM;
538 }
539 if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
540 == COPYFAIL) {
541 rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
542 p->RIOError.Error = COPYIN_FAILED;
543 return -EFAULT;
544 }
545 return RIOAssignRta(p, &MapEnt);
546
547 case RIO_CHANGE_NAME:
548 rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n");
549 if ( !su ) {
550 rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n");
551 p->RIOError.Error = NOT_SUPER_USER;
552 return -EPERM;
553 }
554 if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
555 == COPYFAIL) {
556 rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
557 p->RIOError.Error = COPYIN_FAILED;
558 return -EFAULT;
559 }
560 return RIOChangeName(p, &MapEnt);
561
562 case RIO_DELETE_RTA:
563 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n");
564 if ( !su ) {
565 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n");
566 p->RIOError.Error = NOT_SUPER_USER;
567 return -EPERM;
568 }
569 if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
570 == COPYFAIL ) {
571 rio_dprintk (RIO_DEBUG_CTRL, "Copy from data space failed\n");
572 p->RIOError.Error = COPYIN_FAILED;
573 return -EFAULT;
574 }
575 return RIODeleteRta(p, &MapEnt);
576
577 case RIO_QUICK_CHECK:
578 /*
579 ** 09.12.1998 ARG - ESIL 0776 part fix
580 ** A customer was using this to get the RTAs
581 ** connect/disconnect status.
582 ** RIOConCon() had been botched use RIOHalted
583 ** to keep track of RTA connections and
584 ** disconnections. That has been changed and
585 ** RIORtaDisCons in the rio_info struct now
586 ** does the job. So we need to return the value
587 ** of RIORtaCons instead of RIOHalted.
588 **
589 if (copyout((caddr_t)&p->RIOHalted,(int)arg,
590 sizeof(uint))==COPYFAIL) {
591 **
592 */
593
594 if (copyout((caddr_t)&p->RIORtaDisCons,(int)arg,
595 sizeof(uint))==COPYFAIL) {
596 p->RIOError.Error = COPYOUT_FAILED;
597 return -EFAULT;
598 }
599 return 0;
600
601 case RIO_LAST_ERROR:
602 if (copyout((caddr_t)&p->RIOError, (int)arg,
603 sizeof(struct Error)) ==COPYFAIL )
604 return -EFAULT;
605 return 0;
606
607 case RIO_GET_LOG:
608 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_LOG\n");
609#ifdef LOGGING
610 RIOGetLog(arg);
611 return 0;
612#else
613 return -EINVAL;
614#endif
615
616 case RIO_GET_MODTYPE:
617 if ( copyin( (int)arg, (caddr_t)&port,
618 sizeof(uint)) == COPYFAIL )
619 {
620 p->RIOError.Error = COPYIN_FAILED;
621 return -EFAULT;
622 }
623 rio_dprintk (RIO_DEBUG_CTRL, "Get module type for port %d\n", port);
624 if ( port < 0 || port > 511 )
625 {
626 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port);
627 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
628 return -EINVAL;
629 }
630 PortP = (p->RIOPortp[port]);
631 if (!PortP->Mapped)
632 {
633 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port);
634 p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
635 return -EINVAL;
636 }
637 /*
638 ** Return module type of port
639 */
640 port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes;
641 if (copyout((caddr_t)&port, (int)arg,
642 sizeof(uint)) == COPYFAIL) {
643 p->RIOError.Error = COPYOUT_FAILED;
644 return -EFAULT;
645 }
646 return(0);
647 /*
648 ** 02.03.1999 ARG - ESIL 0820 fix
649 ** We are no longer using "Boot Mode", so these ioctls
650 ** are not required :
651 **
652 case RIO_GET_BOOT_MODE :
653 rio_dprint(RIO_DEBUG_CTRL, ("Get boot mode - %x\n", p->RIOBootMode));
654 **
655 ** Return boot state of system - BOOT_ALL, BOOT_OWN or BOOT_NONE
656 **
657 if (copyout((caddr_t)&p->RIOBootMode, (int)arg,
658 sizeof(p->RIOBootMode)) == COPYFAIL) {
659 p->RIOError.Error = COPYOUT_FAILED;
660 return -EFAULT;
661 }
662 return(0);
663
664 case RIO_SET_BOOT_MODE :
665 p->RIOBootMode = (uint) arg;
666 rio_dprint(RIO_DEBUG_CTRL, ("Set boot mode to 0x%x\n", p->RIOBootMode));
667 return(0);
668 **
669 ** End ESIL 0820 fix
670 */
671
672 case RIO_BLOCK_OPENS:
673 rio_dprintk (RIO_DEBUG_CTRL, "Opens block until booted\n");
674 for ( Entry=0; Entry < RIO_PORTS; Entry++ ) {
675 rio_spin_lock_irqsave(&PortP->portSem, flags);
676 p->RIOPortp[Entry]->WaitUntilBooted = 1;
677 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
678 }
679 return 0;
680
681 case RIO_SETUP_PORTS:
682 rio_dprintk (RIO_DEBUG_CTRL, "Setup ports\n");
683 if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup))
684 == COPYFAIL ) {
685 p->RIOError.Error = COPYIN_FAILED;
686 rio_dprintk (RIO_DEBUG_CTRL, "EFAULT");
687 return -EFAULT;
688 }
689 if ( PortSetup.From > PortSetup.To ||
690 PortSetup.To >= RIO_PORTS ) {
691 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
692 rio_dprintk (RIO_DEBUG_CTRL, "ENXIO");
693 return -ENXIO;
694 }
695 if ( PortSetup.XpCps > p->RIOConf.MaxXpCps ||
696 PortSetup.XpCps < p->RIOConf.MinXpCps ) {
697 p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;
698 rio_dprintk (RIO_DEBUG_CTRL, "EINVAL");
699 return -EINVAL;
700 }
701 if ( !p->RIOPortp ) {
702 cprintf("No p->RIOPortp array!\n");
703 rio_dprintk (RIO_DEBUG_CTRL, "No p->RIOPortp array!\n");
704 return -EIO;
705 }
706 rio_dprintk (RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To);
707 for (loop=PortSetup.From; loop<=PortSetup.To; loop++) {
708 rio_dprintk (RIO_DEBUG_CTRL, "in loop (%d)!\n", loop);
709#if 0
710 PortP = p->RIOPortp[loop];
711 if ( !PortP->TtyP )
712 PortP->TtyP = &p->channel[loop];
713
714 rio_spin_lock_irqsave(&PortP->portSem, flags);
715 if ( PortSetup.IxAny )
716 PortP->Config |= RIO_IXANY;
717 else
718 PortP->Config &= ~RIO_IXANY;
719 if ( PortSetup.IxOn )
720 PortP->Config |= RIO_IXON;
721 else
722 PortP->Config &= ~RIO_IXON;
723
724 /*
725 ** If the port needs to wait for all a processes output
726 ** to drain before closing then this flag will be set.
727 */
728 if (PortSetup.Drain) {
729 PortP->Config |= RIO_WAITDRAIN;
730 } else {
731 PortP->Config &= ~RIO_WAITDRAIN;
732 }
733 /*
734 ** Store settings if locking or unlocking port or if the
735 ** port is not locked, when setting the store option.
736 */
737 if (PortP->Mapped &&
738 ((PortSetup.Lock && !PortP->Lock) ||
739 (!PortP->Lock &&
740 (PortSetup.Store && !PortP->Store)))) {
741 PortP->StoredTty.iflag = PortP->TtyP->tm.c_iflag;
742 PortP->StoredTty.oflag = PortP->TtyP->tm.c_oflag;
743 PortP->StoredTty.cflag = PortP->TtyP->tm.c_cflag;
744 PortP->StoredTty.lflag = PortP->TtyP->tm.c_lflag;
745 PortP->StoredTty.line = PortP->TtyP->tm.c_line;
746 bcopy(PortP->TtyP->tm.c_cc, PortP->StoredTty.cc,
747 NCC + 5);
748 }
749 PortP->Lock = PortSetup.Lock;
750 PortP->Store = PortSetup.Store;
751 PortP->Xprint.XpCps = PortSetup.XpCps;
752 bcopy(PortSetup.XpOn,PortP->Xprint.XpOn,MAX_XP_CTRL_LEN);
753 bcopy(PortSetup.XpOff,PortP->Xprint.XpOff,MAX_XP_CTRL_LEN);
754 PortP->Xprint.XpOn[MAX_XP_CTRL_LEN-1] = '\0';
755 PortP->Xprint.XpOff[MAX_XP_CTRL_LEN-1] = '\0';
756 PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+
757 RIOStrlen(PortP->Xprint.XpOff);
758 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
759#endif
760 }
761 rio_dprintk (RIO_DEBUG_CTRL, "after loop (%d)!\n", loop);
762 rio_dprintk (RIO_DEBUG_CTRL, "Retval:%x\n", retval);
763 return retval;
764
765 case RIO_GET_PORT_SETUP :
766 rio_dprintk (RIO_DEBUG_CTRL, "Get port setup\n");
767 if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup))
768 == COPYFAIL ) {
769 p->RIOError.Error = COPYIN_FAILED;
770 return -EFAULT;
771 }
772 if ( PortSetup.From >= RIO_PORTS ) {
773 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
774 return -ENXIO;
775 }
776
777 port = PortSetup.To = PortSetup.From;
778 PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ?
779 1 : 0;
780 PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ?
781 1 : 0;
782 PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ?
783 1 : 0;
784 PortSetup.Store = p->RIOPortp[port]->Store;
785 PortSetup.Lock = p->RIOPortp[port]->Lock;
786 PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps;
787 bcopy(p->RIOPortp[port]->Xprint.XpOn, PortSetup.XpOn,
788 MAX_XP_CTRL_LEN);
789 bcopy(p->RIOPortp[port]->Xprint.XpOff, PortSetup.XpOff,
790 MAX_XP_CTRL_LEN);
791 PortSetup.XpOn[MAX_XP_CTRL_LEN-1] = '\0';
792 PortSetup.XpOff[MAX_XP_CTRL_LEN-1] = '\0';
793
794 if ( copyout((caddr_t)&PortSetup,(int)arg,sizeof(PortSetup))
795 ==COPYFAIL ) {
796 p->RIOError.Error = COPYOUT_FAILED;
797 return -EFAULT;
798 }
799 return retval;
800
801 case RIO_GET_PORT_PARAMS :
802 rio_dprintk (RIO_DEBUG_CTRL, "Get port params\n");
803 if (copyin( (int)arg, (caddr_t)&PortParams,
804 sizeof(struct PortParams)) == COPYFAIL) {
805 p->RIOError.Error = COPYIN_FAILED;
806 return -EFAULT;
807 }
808 if (PortParams.Port >= RIO_PORTS) {
809 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
810 return -ENXIO;
811 }
812 PortP = (p->RIOPortp[PortParams.Port]);
813 PortParams.Config = PortP->Config;
814 PortParams.State = PortP->State;
815 rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
816
817 if (copyout((caddr_t)&PortParams, (int)arg,
818 sizeof(struct PortParams)) == COPYFAIL ) {
819 p->RIOError.Error = COPYOUT_FAILED;
820 return -EFAULT;
821 }
822 return retval;
823
824 case RIO_GET_PORT_TTY :
825 rio_dprintk (RIO_DEBUG_CTRL, "Get port tty\n");
826 if (copyin((int)arg, (caddr_t)&PortTty, sizeof(struct PortTty))
827 == COPYFAIL) {
828 p->RIOError.Error = COPYIN_FAILED;
829 return -EFAULT;
830 }
831 if ( PortTty.port >= RIO_PORTS ) {
832 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
833 return -ENXIO;
834 }
835
836 rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
837 PortP = (p->RIOPortp[PortTty.port]);
838#if 0
839 PortTty.Tty.tm.c_iflag = PortP->TtyP->tm.c_iflag;
840 PortTty.Tty.tm.c_oflag = PortP->TtyP->tm.c_oflag;
841 PortTty.Tty.tm.c_cflag = PortP->TtyP->tm.c_cflag;
842 PortTty.Tty.tm.c_lflag = PortP->TtyP->tm.c_lflag;
843#endif
844 if (copyout((caddr_t)&PortTty, (int)arg,
845 sizeof(struct PortTty)) == COPYFAIL) {
846 p->RIOError.Error = COPYOUT_FAILED;
847 return -EFAULT;
848 }
849 return retval;
850
851 case RIO_SET_PORT_TTY :
852 if (copyin((int)arg, (caddr_t)&PortTty,
853 sizeof(struct PortTty)) == COPYFAIL) {
854 p->RIOError.Error = COPYIN_FAILED;
855 return -EFAULT;
856 }
857 rio_dprintk (RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port);
858 if (PortTty.port >= (ushort) RIO_PORTS) {
859 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
860 return -ENXIO;
861 }
862 PortP = (p->RIOPortp[PortTty.port]);
863#if 0
864 rio_spin_lock_irqsave(&PortP->portSem, flags);
865 PortP->TtyP->tm.c_iflag = PortTty.Tty.tm.c_iflag;
866 PortP->TtyP->tm.c_oflag = PortTty.Tty.tm.c_oflag;
867 PortP->TtyP->tm.c_cflag = PortTty.Tty.tm.c_cflag;
868 PortP->TtyP->tm.c_lflag = PortTty.Tty.tm.c_lflag;
869 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
870#endif
871
872 RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP);
873 return retval;
874
875 case RIO_SET_PORT_PARAMS :
876 rio_dprintk (RIO_DEBUG_CTRL, "Set port params\n");
877 if ( copyin((int)arg, (caddr_t)&PortParams, sizeof(PortParams))
878 == COPYFAIL ) {
879 p->RIOError.Error = COPYIN_FAILED;
880 return -EFAULT;
881 }
882 if (PortParams.Port >= (ushort) RIO_PORTS) {
883 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
884 return -ENXIO;
885 }
886 PortP = (p->RIOPortp[PortParams.Port]);
887 rio_spin_lock_irqsave(&PortP->portSem, flags);
888 PortP->Config = PortParams.Config;
889 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
890 return retval;
891
892 case RIO_GET_PORT_STATS :
893 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
894 if ( copyin((int)arg, (caddr_t)&portStats,
895 sizeof(struct portStats)) == COPYFAIL ) {
896 p->RIOError.Error = COPYIN_FAILED;
897 return -EFAULT;
898 }
899 if ( portStats.port >= RIO_PORTS ) {
900 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
901 return -ENXIO;
902 }
903 PortP = (p->RIOPortp[portStats.port]);
904 portStats.gather = PortP->statsGather;
905 portStats.txchars = PortP->txchars;
906 portStats.rxchars = PortP->rxchars;
907 portStats.opens = PortP->opens;
908 portStats.closes = PortP->closes;
909 portStats.ioctls = PortP->ioctls;
910 if ( copyout((caddr_t)&portStats, (int)arg,
911 sizeof(struct portStats)) == COPYFAIL ) {
912 p->RIOError.Error = COPYOUT_FAILED;
913 return -EFAULT;
914 }
915 return retval;
916
917 case RIO_RESET_PORT_STATS :
918 port = (uint) arg;
919 rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
920 if ( port >= RIO_PORTS ) {
921 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
922 return -ENXIO;
923 }
924 PortP = (p->RIOPortp[port]);
925 rio_spin_lock_irqsave(&PortP->portSem, flags);
926 PortP->txchars = 0;
927 PortP->rxchars = 0;
928 PortP->opens = 0;
929 PortP->closes = 0;
930 PortP->ioctls = 0;
931 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
932 return retval;
933
934 case RIO_GATHER_PORT_STATS :
935 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
936 if ( copyin( (int)arg, (caddr_t)&portStats,
937 sizeof(struct portStats)) == COPYFAIL ) {
938 p->RIOError.Error = COPYIN_FAILED;
939 return -EFAULT;
940 }
941 if ( portStats.port >= RIO_PORTS ) {
942 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
943 return -ENXIO;
944 }
945 PortP = (p->RIOPortp[portStats.port]);
946 rio_spin_lock_irqsave(&PortP->portSem, flags);
947 PortP->statsGather = portStats.gather;
948 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
949 return retval;
950
951#ifdef DEBUG_SUPPORTED
952 case RIO_READ_LEVELS:
953 {
954 int num;
955 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_LEVELS\n");
956 for ( num=0; RIODbInf[num].Flag; num++ ) ;
957 rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copy\n",num);
958 if (copyout((caddr_t)RIODbInf,(int)arg,
959 sizeof(struct DbInf)*(num+1))==COPYFAIL) {
960 rio_dprintk (RIO_DEBUG_CTRL, "ReadLevels Copy failed\n");
961 p->RIOError.Error = COPYOUT_FAILED;
962 return -EFAULT;
963 }
964 rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copied\n",num);
965 return retval;
966 }
967#endif
968
969 case RIO_READ_CONFIG:
970 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
971 if (copyout((caddr_t)&p->RIOConf, (int)arg,
972 sizeof(struct Conf)) ==COPYFAIL ) {
973 p->RIOError.Error = COPYOUT_FAILED;
974 return -EFAULT;
975 }
976 return retval;
977
978 case RIO_SET_CONFIG:
979 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n");
980 if ( !su ) {
981 p->RIOError.Error = NOT_SUPER_USER;
982 return -EPERM;
983 }
984 if ( copyin((int)arg, (caddr_t)&p->RIOConf, sizeof(struct Conf) )
985 ==COPYFAIL ) {
986 p->RIOError.Error = COPYIN_FAILED;
987 return -EFAULT;
988 }
989 /*
990 ** move a few value around
991 */
992 for (Host=0; Host < p->RIONumHosts; Host++)
993 if ( (p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING )
994 WWORD(p->RIOHosts[Host].ParmMapP->timer ,
995 p->RIOConf.Timer);
996 return retval;
997
998 case RIO_START_POLLER:
999 rio_dprintk (RIO_DEBUG_CTRL, "RIO_START_POLLER\n");
1000 return -EINVAL;
1001
1002 case RIO_STOP_POLLER:
1003 rio_dprintk (RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n");
1004 if ( !su ) {
1005 p->RIOError.Error = NOT_SUPER_USER;
1006 return -EPERM;
1007 }
1008 p->RIOPolling = NOT_POLLING;
1009 return retval;
1010
1011 case RIO_SETDEBUG:
1012 case RIO_GETDEBUG:
1013 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
1014 if ( copyin( (int)arg, (caddr_t)&DebugCtrl, sizeof(DebugCtrl) )
1015 ==COPYFAIL ) {
1016 p->RIOError.Error = COPYIN_FAILED;
1017 return -EFAULT;
1018 }
1019 if ( DebugCtrl.SysPort == NO_PORT ) {
1020 if ( cmd == RIO_SETDEBUG ) {
1021 if ( !su ) {
1022 p->RIOError.Error = NOT_SUPER_USER;
1023 return -EPERM;
1024 }
1025 p->rio_debug = DebugCtrl.Debug;
1026 p->RIODebugWait = DebugCtrl.Wait;
1027 rio_dprintk (RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n",
1028 p->rio_debug,p->RIODebugWait);
1029 }
1030 else {
1031 rio_dprintk (RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n",
1032 p->rio_debug,p->RIODebugWait);
1033 DebugCtrl.Debug = p->rio_debug;
1034 DebugCtrl.Wait = p->RIODebugWait;
1035 if ( copyout((caddr_t)&DebugCtrl,(int)arg,
1036 sizeof(DebugCtrl)) == COPYFAIL ) {
1037 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
1038 DebugCtrl.SysPort);
1039 p->RIOError.Error = COPYOUT_FAILED;
1040 return -EFAULT;
1041 }
1042 }
1043 }
1044 else if ( DebugCtrl.SysPort >= RIO_PORTS &&
1045 DebugCtrl.SysPort != NO_PORT ) {
1046 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
1047 DebugCtrl.SysPort);
1048 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1049 return -ENXIO;
1050 }
1051 else if ( cmd == RIO_SETDEBUG ) {
1052 if ( !su ) {
1053 p->RIOError.Error = NOT_SUPER_USER;
1054 return -EPERM;
1055 }
1056 rio_spin_lock_irqsave(&PortP->portSem, flags);
1057 p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug;
1058 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1059 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n",
1060 p->RIOPortp[DebugCtrl.SysPort]->Debug);
1061 }
1062 else {
1063 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n",
1064 p->RIOPortp[DebugCtrl.SysPort]->Debug);
1065 DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
1066 if ( copyout((caddr_t)&DebugCtrl,(int)arg,
1067 sizeof(DebugCtrl))==COPYFAIL ) {
1068 rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
1069 p->RIOError.Error = COPYOUT_FAILED;
1070 return -EFAULT;
1071 }
1072 }
1073 return retval;
1074
1075 case RIO_VERSID:
1076 /*
1077 ** Enquire about the release and version.
1078 ** We return MAX_VERSION_LEN bytes, being a
1079 ** textual null terminated string.
1080 */
1081 rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID\n");
1082 if ( copyout( (caddr_t)RIOVersid(),
1083 (int)arg,
1084 sizeof(struct rioVersion) ) == COPYFAIL )
1085 {
1086 rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
1087 p->RIOError.Error = COPYOUT_FAILED;
1088 return -EFAULT;
1089 }
1090 return retval;
1091
1092 /*
1093 ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1094 ** !! commented out previous 'RIO_VERSID' functionality !!
1095 ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1096 **
1097 case RIO_VERSID:
1098 **
1099 ** Enquire about the release and version.
1100 ** We return MAX_VERSION_LEN bytes, being a textual null
1101 ** terminated string.
1102 **
1103 rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID\n"));
1104 if (copyout((caddr_t)RIOVersid(),
1105 (int)arg, MAX_VERSION_LEN ) == COPYFAIL ) {
1106 rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID: Bad copy to user space\n",Host));
1107 p->RIOError.Error = COPYOUT_FAILED;
1108 return -EFAULT;
1109 }
1110 return retval;
1111 **
1112 ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1113 */
1114
1115 case RIO_NUM_HOSTS:
1116 /*
1117 ** Enquire as to the number of hosts located
1118 ** at init time.
1119 */
1120 rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
1121 if (copyout((caddr_t)&p->RIONumHosts, (int)arg,
1122 sizeof(p->RIONumHosts) )==COPYFAIL ) {
1123 rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
1124 p->RIOError.Error = COPYOUT_FAILED;
1125 return -EFAULT;
1126 }
1127 return retval;
1128
1129 case RIO_HOST_FOAD:
1130 /*
1131 ** Kill host. This may not be in the final version...
1132 */
1133 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD %d\n", (int)arg);
1134 if ( !su ) {
1135 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
1136 p->RIOError.Error = NOT_SUPER_USER;
1137 return -EPERM;
1138 }
1139 p->RIOHalted = 1;
1140 p->RIOSystemUp = 0;
1141
1142 for ( Host=0; Host<p->RIONumHosts; Host++ ) {
1143 (void)RIOBoardTest( p->RIOHosts[Host].PaddrP,
1144 p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type,
1145 p->RIOHosts[Host].Slot );
1146 bzero( (caddr_t)&p->RIOHosts[Host].Flags,
1147 ((int)&p->RIOHosts[Host].____end_marker____) -
1148 ((int)&p->RIOHosts[Host].Flags) );
1149 p->RIOHosts[Host].Flags = RC_WAITING;
1150#if 0
1151 RIOSetupDataStructs(p);
1152#endif
1153 }
1154 RIOFoadWakeup(p);
1155 p->RIONumBootPkts = 0;
1156 p->RIOBooting = 0;
1157
1158#ifdef RINGBUFFER_SUPPORT
1159 for( loop=0; loop<RIO_PORTS; loop++ )
1160 if ( p->RIOPortp[loop]->TxRingBuffer )
1161 sysfree((void *)p->RIOPortp[loop]->TxRingBuffer,
1162 RIOBufferSize );
1163#endif
1164#if 0
1165 bzero((caddr_t)&p->RIOPortp[0],RIO_PORTS*sizeof(struct Port));
1166#else
1167 printk ("HEEEEELP!\n");
1168#endif
1169
1170 for( loop=0; loop<RIO_PORTS; loop++ ) {
1171#if 0
1172 p->RIOPortp[loop]->TtyP = &p->channel[loop];
1173#endif
1174
1175 spin_lock_init(&p->RIOPortp[loop]->portSem);
1176 p->RIOPortp[loop]->InUse = NOT_INUSE;
1177 }
1178
1179 p->RIOSystemUp = 0;
1180 return retval;
1181
1182 case RIO_DOWNLOAD:
1183 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n");
1184 if ( !su ) {
1185 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n");
1186 p->RIOError.Error = NOT_SUPER_USER;
1187 return -EPERM;
1188 }
1189 if ( copyin((int)arg, (caddr_t)&DownLoad,
1190 sizeof(DownLoad) )==COPYFAIL ) {
1191 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
1192 p->RIOError.Error = COPYIN_FAILED;
1193 return -EFAULT;
1194 }
1195 rio_dprintk (RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n",
1196 DownLoad.ProductCode);
1197
1198 /*
1199 ** It is important that the product code is an unsigned object!
1200 */
1201 if ( DownLoad.ProductCode > MAX_PRODUCT ) {
1202 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n",
1203 DownLoad.ProductCode);
1204 p->RIOError.Error = NO_SUCH_PRODUCT;
1205 return -ENXIO;
1206 }
1207 /*
1208 ** do something!
1209 */
1210 retval = (*(RIOBootTable[DownLoad.ProductCode]))(p, &DownLoad);
1211 /* <-- Panic */
1212 p->RIOHalted = 0;
1213 /*
1214 ** and go back, content with a job well completed.
1215 */
1216 return retval;
1217
1218 case RIO_PARMS:
1219 {
1220 uint host;
1221
1222 if (copyin((int)arg, (caddr_t)&host,
1223 sizeof(host) ) == COPYFAIL ) {
1224 rio_dprintk (RIO_DEBUG_CTRL,
1225 "RIO_HOST_REQ: Copy in from user space failed\n");
1226 p->RIOError.Error = COPYIN_FAILED;
1227 return -EFAULT;
1228 }
1229 /*
1230 ** Fetch the parmmap
1231 */
1232 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS\n");
1233 if ( copyout( (caddr_t)p->RIOHosts[host].ParmMapP,
1234 (int)arg, sizeof(PARM_MAP) )==COPYFAIL ) {
1235 p->RIOError.Error = COPYOUT_FAILED;
1236 rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
1237 return -EFAULT;
1238 }
1239 }
1240 return retval;
1241
1242 case RIO_HOST_REQ:
1243 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
1244 if (copyin((int)arg, (caddr_t)&HostReq,
1245 sizeof(HostReq) )==COPYFAIL ) {
1246 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
1247 p->RIOError.Error = COPYIN_FAILED;
1248 return -EFAULT;
1249 }
1250 if ( HostReq.HostNum >= p->RIONumHosts ) {
1251 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1252 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n",
1253 HostReq.HostNum);
1254 return -ENXIO;
1255 }
1256 rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum);
1257
1258 if (copyout((caddr_t)&p->RIOHosts[HostReq.HostNum],
1259 (int)HostReq.HostP,sizeof(struct Host) ) == COPYFAIL) {
1260 p->RIOError.Error = COPYOUT_FAILED;
1261 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n");
1262 return -EFAULT;
1263 }
1264 return retval;
1265
1266 case RIO_HOST_DPRAM:
1267 rio_dprintk (RIO_DEBUG_CTRL, "Request for DPRAM\n");
1268 if ( copyin( (int)arg, (caddr_t)&HostDpRam,
1269 sizeof(HostDpRam) )==COPYFAIL ) {
1270 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
1271 p->RIOError.Error = COPYIN_FAILED;
1272 return -EFAULT;
1273 }
1274 if ( HostDpRam.HostNum >= p->RIONumHosts ) {
1275 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1276 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n",
1277 HostDpRam.HostNum);
1278 return -ENXIO;
1279 }
1280 rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum);
1281
1282 if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) {
1283 int off;
1284 /* It's hardware like this that really gets on my tits. */
1285 static unsigned char copy[sizeof(struct DpRam)];
1286 for ( off=0; off<sizeof(struct DpRam); off++ )
1287 copy[off] = p->RIOHosts[HostDpRam.HostNum].Caddr[off];
1288 if ( copyout( (caddr_t)copy, (int)HostDpRam.DpRamP,
1289 sizeof(struct DpRam) ) == COPYFAIL ) {
1290 p->RIOError.Error = COPYOUT_FAILED;
1291 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
1292 return -EFAULT;
1293 }
1294 }
1295 else if (copyout((caddr_t)p->RIOHosts[HostDpRam.HostNum].Caddr,
1296 (int)HostDpRam.DpRamP,
1297 sizeof(struct DpRam) ) == COPYFAIL ) {
1298 p->RIOError.Error = COPYOUT_FAILED;
1299 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
1300 return -EFAULT;
1301 }
1302 return retval;
1303
1304 case RIO_SET_BUSY:
1305 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
1306 if ( (int)arg < 0 || (int)arg > 511 ) {
1307 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %d\n",(int)arg);
1308 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1309 return -EINVAL;
1310 }
1311 rio_spin_lock_irqsave(&PortP->portSem, flags);
1312 p->RIOPortp[(int)arg]->State |= RIO_BUSY;
1313 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1314 return retval;
1315
1316 case RIO_HOST_PORT:
1317 /*
1318 ** The daemon want port information
1319 ** (probably for debug reasons)
1320 */
1321 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
1322 if ( copyin((int)arg, (caddr_t)&PortReq,
1323 sizeof(PortReq) )==COPYFAIL ) {
1324 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
1325 p->RIOError.Error = COPYIN_FAILED;
1326 return -EFAULT;
1327 }
1328
1329 if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */
1330 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n",
1331 PortReq.SysPort);
1332 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1333 return -ENXIO;
1334 }
1335 rio_dprintk (RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort);
1336 if (copyout((caddr_t)p->RIOPortp[PortReq.SysPort],
1337 (int)PortReq.PortP,
1338 sizeof(struct Port) ) == COPYFAIL) {
1339 p->RIOError.Error = COPYOUT_FAILED;
1340 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n");
1341 return -EFAULT;
1342 }
1343 return retval;
1344
1345 case RIO_HOST_RUP:
1346 /*
1347 ** The daemon want rup information
1348 ** (probably for debug reasons)
1349 */
1350 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
1351 if (copyin((int)arg, (caddr_t)&RupReq,
1352 sizeof(RupReq) )==COPYFAIL ) {
1353 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
1354 p->RIOError.Error = COPYIN_FAILED;
1355 return -EFAULT;
1356 }
1357 if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */
1358 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n",
1359 RupReq.HostNum);
1360 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1361 return -ENXIO;
1362 }
1363 if ( RupReq.RupNum >= MAX_RUP+LINKS_PER_UNIT ) { /* eek! */
1364 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n",
1365 RupReq.RupNum);
1366 p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
1367 return -EINVAL;
1368 }
1369 HostP = &p->RIOHosts[RupReq.HostNum];
1370
1371 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
1372 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n",
1373 RupReq.HostNum);
1374 p->RIOError.Error = HOST_NOT_RUNNING;
1375 return -EIO;
1376 }
1377 rio_dprintk (RIO_DEBUG_CTRL, "Request for rup %d from host %d\n",
1378 RupReq.RupNum,RupReq.HostNum);
1379
1380 if (copyout((caddr_t)HostP->UnixRups[RupReq.RupNum].RupP,
1381 (int)RupReq.RupP,sizeof(struct RUP) ) == COPYFAIL) {
1382 p->RIOError.Error = COPYOUT_FAILED;
1383 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
1384 return -EFAULT;
1385 }
1386 return retval;
1387
1388 case RIO_HOST_LPB:
1389 /*
1390 ** The daemon want lpb information
1391 ** (probably for debug reasons)
1392 */
1393 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
1394 if (copyin((int)arg, (caddr_t)&LpbReq,
1395 sizeof(LpbReq) )==COPYFAIL ) {
1396 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
1397 p->RIOError.Error = COPYIN_FAILED;
1398 return -EFAULT;
1399 }
1400 if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */
1401 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n",
1402 LpbReq.Host);
1403 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1404 return -ENXIO;
1405 }
1406 if ( LpbReq.Link >= LINKS_PER_UNIT ) { /* eek! */
1407 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n",
1408 LpbReq.Link);
1409 p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE;
1410 return -EINVAL;
1411 }
1412 HostP = &p->RIOHosts[LpbReq.Host];
1413
1414 if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
1415 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n",
1416 LpbReq.Host );
1417 p->RIOError.Error = HOST_NOT_RUNNING;
1418 return -EIO;
1419 }
1420 rio_dprintk (RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n",
1421 LpbReq.Link, LpbReq.Host);
1422
1423 if (copyout((caddr_t)&HostP->LinkStrP[LpbReq.Link],
1424 (int)LpbReq.LpbP,sizeof(struct LPB) ) == COPYFAIL) {
1425 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
1426 p->RIOError.Error = COPYOUT_FAILED;
1427 return -EFAULT;
1428 }
1429 return retval;
1430
1431 /*
1432 ** Here 3 IOCTL's that allow us to change the way in which
1433 ** rio logs errors. send them just to syslog or send them
1434 ** to both syslog and console or send them to just the console.
1435 **
1436 ** See RioStrBuf() in util.c for the other half.
1437 */
1438 case RIO_SYSLOG_ONLY:
1439 p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */
1440 return 0;
1441
1442 case RIO_SYSLOG_CONS:
1443 p->RIOPrintLogState = PRINT_TO_LOG_CONS;/* syslog and console */
1444 return 0;
1445
1446 case RIO_CONS_ONLY:
1447 p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */
1448 return 0;
1449
1450 case RIO_SIGNALS_ON:
1451 if ( p->RIOSignalProcess ) {
1452 p->RIOError.Error = SIGNALS_ALREADY_SET;
1453 return -EBUSY;
1454 }
1455 p->RIOSignalProcess = getpid();
1456 p->RIOPrintDisabled = DONT_PRINT;
1457 return retval;
1458
1459 case RIO_SIGNALS_OFF:
1460 if ( p->RIOSignalProcess != getpid() ) {
1461 p->RIOError.Error = NOT_RECEIVING_PROCESS;
1462 return -EPERM;
1463 }
1464 rio_dprintk (RIO_DEBUG_CTRL, "Clear signal process to zero\n");
1465 p->RIOSignalProcess = 0;
1466 return retval;
1467
1468 case RIO_SET_BYTE_MODE:
1469 for ( Host=0; Host<p->RIONumHosts; Host++ )
1470 if ( p->RIOHosts[Host].Type == RIO_AT )
1471 p->RIOHosts[Host].Mode &= ~WORD_OPERATION;
1472 return retval;
1473
1474 case RIO_SET_WORD_MODE:
1475 for ( Host=0; Host<p->RIONumHosts; Host++ )
1476 if ( p->RIOHosts[Host].Type == RIO_AT )
1477 p->RIOHosts[Host].Mode |= WORD_OPERATION;
1478 return retval;
1479
1480 case RIO_SET_FAST_BUS:
1481 for ( Host=0; Host<p->RIONumHosts; Host++ )
1482 if ( p->RIOHosts[Host].Type == RIO_AT )
1483 p->RIOHosts[Host].Mode |= FAST_AT_BUS;
1484 return retval;
1485
1486 case RIO_SET_SLOW_BUS:
1487 for ( Host=0; Host<p->RIONumHosts; Host++ )
1488 if ( p->RIOHosts[Host].Type == RIO_AT )
1489 p->RIOHosts[Host].Mode &= ~FAST_AT_BUS;
1490 return retval;
1491
1492 case RIO_MAP_B50_TO_50:
1493 case RIO_MAP_B50_TO_57600:
1494 case RIO_MAP_B110_TO_110:
1495 case RIO_MAP_B110_TO_115200:
1496 rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping\n");
1497 port = (uint) arg;
1498 if ( port < 0 || port > 511 ) {
1499 rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
1500 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1501 return -EINVAL;
1502 }
1503 rio_spin_lock_irqsave(&PortP->portSem, flags);
1504 switch( cmd )
1505 {
1506 case RIO_MAP_B50_TO_50 :
1507 p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50;
1508 break;
1509 case RIO_MAP_B50_TO_57600 :
1510 p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50;
1511 break;
1512 case RIO_MAP_B110_TO_110 :
1513 p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110;
1514 break;
1515 case RIO_MAP_B110_TO_115200 :
1516 p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110;
1517 break;
1518 }
1519 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1520 return retval;
1521
1522 case RIO_STREAM_INFO:
1523 rio_dprintk (RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n");
1524 return -EINVAL;
1525
1526 case RIO_SEND_PACKET:
1527 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
1528 if ( copyin( (int)arg, (caddr_t)&SendPack,
1529 sizeof(SendPack) )==COPYFAIL ) {
1530 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
1531 p->RIOError.Error = COPYIN_FAILED;
1532 return -EFAULT;
1533 }
1534 if ( SendPack.PortNum >= 128 ) {
1535 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1536 return -ENXIO;
1537 }
1538
1539 PortP = p->RIOPortp[SendPack.PortNum];
1540 rio_spin_lock_irqsave(&PortP->portSem, flags);
1541
1542 if ( !can_add_transmit(&PacketP,PortP) ) {
1543 p->RIOError.Error = UNIT_IS_IN_USE;
1544 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1545 return -ENOSPC;
1546 }
1547
1548 for ( loop=0; loop<(ushort)(SendPack.Len & 127); loop++ )
1549 WBYTE(PacketP->data[loop], SendPack.Data[loop] );
1550
1551 WBYTE(PacketP->len, SendPack.Len);
1552
1553 add_transmit( PortP );
1554 /*
1555 ** Count characters transmitted for port statistics reporting
1556 */
1557 if (PortP->statsGather)
1558 PortP->txchars += (SendPack.Len & 127);
1559 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1560 return retval;
1561
1562 case RIO_NO_MESG:
1563 if ( su )
1564 p->RIONoMessage = 1;
1565 return su ? 0 : -EPERM;
1566
1567 case RIO_MESG:
1568 if ( su )
1569 p->RIONoMessage = 0;
1570 return su ? 0 : -EPERM;
1571
1572 case RIO_WHAT_MESG:
1573 if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg,
1574 sizeof(p->RIONoMessage) )==COPYFAIL ) {
1575 rio_dprintk (RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
1576 p->RIOError.Error = COPYOUT_FAILED;
1577 return -EFAULT;
1578 }
1579 return 0;
1580
1581 case RIO_MEM_DUMP :
1582 if (copyin((int)arg, (caddr_t)&SubCmd,
1583 sizeof(struct SubCmdStruct)) == COPYFAIL) {
1584 p->RIOError.Error = COPYIN_FAILED;
1585 return -EFAULT;
1586 }
1587 rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n",
1588 SubCmd.Host, SubCmd.Rup, SubCmd.Addr);
1589
1590 if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) {
1591 p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
1592 return -EINVAL;
1593 }
1594
1595 if (SubCmd.Host >= p->RIONumHosts ) {
1596 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1597 return -EINVAL;
1598 }
1599
1600 port = p->RIOHosts[SubCmd.Host].
1601 UnixRups[SubCmd.Rup].BaseSysPort;
1602
1603 PortP = p->RIOPortp[port];
1604
1605 rio_spin_lock_irqsave(&PortP->portSem, flags);
1606
1607 if ( RIOPreemptiveCmd(p, PortP, MEMDUMP ) == RIO_FAIL ) {
1608 rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n");
1609 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1610 return -EBUSY;
1611 }
1612 else
1613 PortP->State |= RIO_BUSY;
1614
1615 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1616 if ( copyout( (caddr_t)p->RIOMemDump, (int)arg,
1617 MEMDUMP_SIZE) == COPYFAIL ) {
1618 rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
1619 p->RIOError.Error = COPYOUT_FAILED;
1620 return -EFAULT;
1621 }
1622 return 0;
1623
1624 case RIO_TICK:
1625 if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
1626 return -EINVAL;
1627 rio_dprintk (RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int)arg);
1628 WBYTE(p->RIOHosts[(int)arg].SetInt , 0xff);
1629 return 0;
1630
1631 case RIO_TOCK:
1632 if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
1633 return -EINVAL;
1634 rio_dprintk (RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int)arg);
1635 WBYTE((p->RIOHosts[(int)arg].ResetInt) , 0xff);
1636 return 0;
1637
1638 case RIO_READ_CHECK:
1639 /* Check reads for pkts with data[0] the same */
1640 p->RIOReadCheck = !p->RIOReadCheck;
1641 if (copyout((caddr_t)&p->RIOReadCheck,(int)arg,
1642 sizeof(uint))== COPYFAIL) {
1643 p->RIOError.Error = COPYOUT_FAILED;
1644 return -EFAULT;
1645 }
1646 return 0;
1647
1648 case RIO_READ_REGISTER :
1649 if (copyin((int)arg, (caddr_t)&SubCmd,
1650 sizeof(struct SubCmdStruct)) == COPYFAIL) {
1651 p->RIOError.Error = COPYIN_FAILED;
1652 return -EFAULT;
1653 }
1654 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n",
1655 SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr);
1656
1657 if (SubCmd.Port > 511) {
1658 rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n",
1659 SubCmd.Port);
1660 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1661 return -EINVAL;
1662 }
1663
1664 if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) {
1665 p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
1666 return -EINVAL;
1667 }
1668
1669 if (SubCmd.Host >= p->RIONumHosts ) {
1670 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1671 return -EINVAL;
1672 }
1673
1674 port = p->RIOHosts[SubCmd.Host].
1675 UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port;
1676 PortP = p->RIOPortp[port];
1677
1678 rio_spin_lock_irqsave(&PortP->portSem, flags);
1679
1680 if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) {
1681 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n");
1682 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1683 return -EBUSY;
1684 }
1685 else
1686 PortP->State |= RIO_BUSY;
1687
1688 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
1689 if (copyout((caddr_t)&p->CdRegister, (int)arg,
1690 sizeof(uint)) == COPYFAIL ) {
1691 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
1692 p->RIOError.Error = COPYOUT_FAILED;
1693 return -EFAULT;
1694 }
1695 return 0;
1696 /*
1697 ** rio_make_dev: given port number (0-511) ORed with port type
1698 ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t
1699 ** value to pass to mknod to create the correct device node.
1700 */
1701 case RIO_MAKE_DEV:
1702 {
1703 uint port = (uint)arg & RIO_MODEM_MASK;
1704
1705 switch ( (uint)arg & RIO_DEV_MASK ) {
1706 case RIO_DEV_DIRECT:
1707 arg = (caddr_t)drv_makedev(MAJOR(dev), port);
1708 rio_dprintk (RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n",port, (int)arg);
1709 return (int)arg;
1710 case RIO_DEV_MODEM:
1711 arg = (caddr_t)drv_makedev(MAJOR(dev), (port|RIO_MODEM_BIT) );
1712 rio_dprintk (RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n",port, (int)arg);
1713 return (int)arg;
1714 case RIO_DEV_XPRINT:
1715 arg = (caddr_t)drv_makedev(MAJOR(dev), port);
1716 rio_dprintk (RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n",port, (int)arg);
1717 return (int)arg;
1718 }
1719 rio_dprintk (RIO_DEBUG_CTRL, "MAKE Device is called\n");
1720 return -EINVAL;
1721 }
1722 /*
1723 ** rio_minor: given a dev_t from a stat() call, return
1724 ** the port number (0-511) ORed with the port type
1725 ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT )
1726 */
1727 case RIO_MINOR:
1728 {
1729 dev_t dv;
1730 int mino;
1731
1732 dv = (dev_t)((int)arg);
1733 mino = RIO_UNMODEM(dv);
1734
1735 if ( RIO_ISMODEM(dv) ) {
1736 rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino);
1737 arg = (caddr_t)(mino | RIO_DEV_MODEM);
1738 }
1739 else {
1740 rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino);
1741 arg = (caddr_t)(mino | RIO_DEV_DIRECT);
1742 }
1743 return (int)arg;
1744 }
1745 }
1746 rio_dprintk (RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n",cmd);
1747 p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
1748
1749 func_exit ();
1750 return -EINVAL;
1751}
1752
1753/*
1754** Pre-emptive commands go on RUPs and are only one byte long.
1755*/
1756int
1757RIOPreemptiveCmd(p, PortP, Cmd)
1758struct rio_info * p;
1759struct Port *PortP;
1760uchar Cmd;
1761{
1762 struct CmdBlk *CmdBlkP;
1763 struct PktCmd_M *PktCmdP;
1764 int Ret;
1765 ushort rup;
1766 int port;
1767
1768#ifdef CHECK
1769 CheckPortP( PortP );
1770#endif
1771
1772 if ( PortP->State & RIO_DELETED ) {
1773 rio_dprintk (RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n");
1774 return RIO_FAIL;
1775 }
1776
1777 if (((int)((char)PortP->InUse) == -1) || ! (CmdBlkP = RIOGetCmdBlk()) ) {
1778 rio_dprintk (RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n",
1779 Cmd, PortP->PortNum);
1780 return RIO_FAIL;
1781 }
1782
1783 rio_dprintk (RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n",
1784 (int)CmdBlkP,PortP->InUse);
1785
1786 PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0];
1787
1788 CmdBlkP->Packet.src_unit = 0;
1789 if (PortP->SecondBlock)
1790 rup = PortP->ID2;
1791 else
1792 rup = PortP->RupNum;
1793 CmdBlkP->Packet.dest_unit = rup;
1794 CmdBlkP->Packet.src_port = COMMAND_RUP;
1795 CmdBlkP->Packet.dest_port = COMMAND_RUP;
1796 CmdBlkP->Packet.len = PKT_CMD_BIT | 2;
1797 CmdBlkP->PostFuncP = RIOUnUse;
1798 CmdBlkP->PostArg = (int)PortP;
1799 PktCmdP->Command = Cmd;
1800 port = PortP->HostPort % (ushort)PORTS_PER_RTA;
1801 /*
1802 ** Index ports 8-15 for 2nd block of 16 port RTA.
1803 */
1804 if (PortP->SecondBlock)
1805 port += (ushort) PORTS_PER_RTA;
1806 PktCmdP->PhbNum = port;
1807
1808 switch ( Cmd ) {
1809 case MEMDUMP:
1810 rio_dprintk (RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n",
1811 (int)CmdBlkP, (int)SubCmd.Addr);
1812 PktCmdP->SubCommand = MEMDUMP;
1813 PktCmdP->SubAddr = SubCmd.Addr;
1814 break;
1815 case FCLOSE:
1816 rio_dprintk (RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP);
1817 break;
1818 case READ_REGISTER:
1819 rio_dprintk (RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n",
1820 (int)SubCmd.Addr, (int)CmdBlkP);
1821 PktCmdP->SubCommand = READ_REGISTER;
1822 PktCmdP->SubAddr = SubCmd.Addr;
1823 break;
1824 case RESUME:
1825 rio_dprintk (RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n",(int)CmdBlkP);
1826 break;
1827 case RFLUSH:
1828 rio_dprintk (RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP);
1829 CmdBlkP->PostFuncP = RIORFlushEnable;
1830 break;
1831 case SUSPEND:
1832 rio_dprintk (RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP);
1833 break;
1834
1835 case MGET :
1836 rio_dprintk (RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int)CmdBlkP);
1837 break;
1838
1839 case MSET :
1840 case MBIC :
1841 case MBIS :
1842 CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
1843 rio_dprintk (RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP);
1844 break;
1845
1846 case WFLUSH:
1847 /*
1848 ** If we have queued up the maximum number of Write flushes
1849 ** allowed then we should not bother sending any more to the
1850 ** RTA.
1851 */
1852 if ((int)((char)PortP->WflushFlag) == (int)-1) {
1853 rio_dprintk (RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!");
1854 RIOFreeCmdBlk(CmdBlkP);
1855 return(RIO_FAIL);
1856 } else {
1857 rio_dprintk (RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n",
1858 (int)CmdBlkP);
1859 CmdBlkP->PostFuncP = RIOWFlushMark;
1860 }
1861 break;
1862 }
1863
1864 PortP->InUse++;
1865
1866 Ret = RIOQueueCmdBlk( PortP->HostP, rup, CmdBlkP );
1867
1868 return Ret;
1869}
diff --git a/drivers/char/rio/riodrvr.h b/drivers/char/rio/riodrvr.h
new file mode 100644
index 000000000000..bc38ac5dfbde
--- /dev/null
+++ b/drivers/char/rio/riodrvr.h
@@ -0,0 +1,144 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riodrvr.h
24** SID : 1.3
25** Last Modified : 11/6/98 09:22:46
26** Retrieved : 11/6/98 09:22:46
27**
28** ident @(#)riodrvr.h 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __riodrvr_h
34#define __riodrvr_h
35
36#include <asm/param.h> /* for HZ */
37
38#ifdef SCCS_LABELS
39static char *_riodrvr_h_sccs_ = "@(#)riodrvr.h 1.3";
40#endif
41
42#define MEMDUMP_SIZE 32
43#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT)
44
45
46struct rio_info {
47 int mode; /* Intr or polled, word/byte */
48 spinlock_t RIOIntrSem; /* Interrupt thread sem */
49 int current_chan; /* current channel */
50 int RIOFailed; /* Not initialised ? */
51 int RIOInstallAttempts; /* no. of rio-install() calls */
52 int RIOLastPCISearch; /* status of last search */
53 int RIONumHosts; /* Number of RIO Hosts */
54 struct Host * RIOHosts; /* RIO Host values */
55 struct Port **RIOPortp; /* RIO port values */
56/*
57** 02.03.1999 ARG - ESIL 0820 fix
58** We no longer use RIOBootMode
59**
60 int RIOBootMode; * RIO boot mode *
61**
62*/
63 int RIOPrintDisabled; /* RIO printing disabled ? */
64 int RIOPrintLogState; /* RIO printing state ? */
65 int RIOPolling; /* Polling ? */
66/*
67** 09.12.1998 ARG - ESIL 0776 part fix
68** The 'RIO_QUICK_CHECK' ioctl was using RIOHalted.
69** The fix for this ESIL introduces another member (RIORtaDisCons) here to be
70** updated in RIOConCon() - to keep track of RTA connections/disconnections.
71** 'RIO_QUICK_CHECK' now returns the value of RIORtaDisCons.
72*/
73 int RIOHalted; /* halted ? */
74 int RIORtaDisCons; /* RTA connections/disconnections */
75 uint RIOReadCheck; /* Rio read check */
76 uint RIONoMessage; /* To display message or not */
77 uint RIONumBootPkts; /* how many packets for an RTA */
78 uint RIOBootCount; /* size of RTA code */
79 uint RIOBooting; /* count of outstanding boots */
80 uint RIOSystemUp; /* Booted ?? */
81 uint RIOCounting; /* for counting interrupts */
82 uint RIOIntCount; /* # of intr since last check */
83 uint RIOTxCount; /* number of xmit intrs */
84 uint RIORxCount; /* number of rx intrs */
85 uint RIORupCount; /* number of rup intrs */
86 int RIXTimer;
87 int RIOBufferSize; /* Buffersize */
88 int RIOBufferMask; /* Buffersize */
89
90 int RIOFirstMajor; /* First host card's major no */
91
92 uint RIOLastPortsMapped; /* highest port number known */
93 uint RIOFirstPortsMapped; /* lowest port number known */
94
95 uint RIOLastPortsBooted; /* highest port number running */
96 uint RIOFirstPortsBooted; /* lowest port number running */
97
98 uint RIOLastPortsOpened; /* highest port number running */
99 uint RIOFirstPortsOpened; /* lowest port number running */
100
101 /* Flag to say that the topology information has been changed. */
102 uint RIOQuickCheck;
103 uint CdRegister; /* ??? */
104 int RIOSignalProcess; /* Signalling process */
105 int rio_debug; /* To debug ... */
106 int RIODebugWait; /* For what ??? */
107 int tpri; /* Thread prio */
108 int tid; /* Thread id */
109 uint _RIO_Polled; /* Counter for polling */
110 uint _RIO_Interrupted; /* Counter for interrupt */
111 int intr_tid; /* iointset return value */
112 int TxEnSem; /* TxEnable Semaphore */
113
114
115 struct Error RIOError; /* to Identify what went wrong */
116 struct Conf RIOConf; /* Configuration ??? */
117 struct ttystatics channel[RIO_PORTS]; /* channel information */
118 char RIOBootPackets[1+(SIXTY_FOUR_K/RTA_BOOT_DATA_SIZE)]
119 [RTA_BOOT_DATA_SIZE];
120 struct Map RIOConnectTable[TOTAL_MAP_ENTRIES];
121 struct Map RIOSavedTable[TOTAL_MAP_ENTRIES];
122
123 /* RTA to host binding table for master/slave operation */
124 ulong RIOBindTab[MAX_RTA_BINDINGS];
125 /* RTA memory dump variable */
126 uchar RIOMemDump[MEMDUMP_SIZE];
127 struct ModuleInfo RIOModuleTypes[MAX_MODULE_TYPES];
128
129};
130
131
132#ifdef linux
133#define debug(x) printk x
134#else
135#define debug(x) kkprintf x
136#endif
137
138
139
140#define RIO_RESET_INT 0x7d80
141#define WRBYTE(x,y) *(volatile unsigned char *)((x)) = \
142 (unsigned char)(y)
143
144#endif /* __riodrvr.h */
diff --git a/drivers/char/rio/rioinfo.h b/drivers/char/rio/rioinfo.h
new file mode 100644
index 000000000000..e08421c9558e
--- /dev/null
+++ b/drivers/char/rio/rioinfo.h
@@ -0,0 +1,96 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rioinfo.h
24** SID : 1.2
25** Last Modified : 11/6/98 14:07:49
26** Retrieved : 11/6/98 14:07:50
27**
28** ident @(#)rioinfo.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rioinfo_h
34#define __rioinfo_h
35
36#ifdef SCCS_LABELS
37static char *_rioinfo_h_sccs_ = "@(#)rioinfo.h 1.2";
38#endif
39
40/*
41** Host card data structure
42*/
43struct RioHostInfo {
44 long location; /* RIO Card Base I/O address */
45 long vector; /* RIO Card IRQ vector */
46 int bus; /* ISA/EISA/MCA/PCI */
47 int mode; /* pointer to host mode - INTERRUPT / POLLED */
48 struct old_sgttyb
49 * Sg; /* pointer to default term characteristics */
50};
51
52
53/* Mode in rio device info */
54#define INTERRUPTED_MODE 0x01 /* Interrupt is generated */
55#define POLLED_MODE 0x02 /* No interrupt */
56#define AUTO_MODE 0x03 /* Auto mode */
57
58#define WORD_ACCESS_MODE 0x10 /* Word Access Mode */
59#define BYTE_ACCESS_MODE 0x20 /* Byte Access Mode */
60
61
62/* Bus type that RIO supports */
63#define ISA_BUS 0x01 /* The card is ISA */
64#define EISA_BUS 0x02 /* The card is EISA */
65#define MCA_BUS 0x04 /* The card is MCA */
66#define PCI_BUS 0x08 /* The card is PCI */
67
68/*
69** 11.11.1998 ARG - ESIL ???? part fix
70** Moved definition for 'CHAN' here from rioinfo.c (it is now
71** called 'DEF_TERM_CHARACTERISTICS').
72*/
73
74#define DEF_TERM_CHARACTERISTICS \
75{ \
76 B19200, B19200, /* input and output speed */ \
77 'H' - '@', /* erase char */ \
78 -1, /* 2nd erase char */ \
79 'U' - '@', /* kill char */ \
80 ECHO | CRMOD, /* mode */ \
81 'C' - '@', /* interrupt character */ \
82 '\\' - '@', /* quit char */ \
83 'Q' - '@', /* start char */ \
84 'S' - '@', /* stop char */ \
85 'D' - '@', /* EOF */ \
86 -1, /* brk */ \
87 (LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */ \
88 'Z' - '@', /* process stop */ \
89 'Y' - '@', /* delayed stop */ \
90 'R' - '@', /* reprint line */ \
91 'O' - '@', /* flush output */ \
92 'W' - '@', /* word erase */ \
93 'V' - '@' /* literal next char */ \
94}
95
96#endif /* __rioinfo_h */
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
new file mode 100644
index 000000000000..dca941ed10cf
--- /dev/null
+++ b/drivers/char/rio/rioinit.c
@@ -0,0 +1,1617 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rioinit.c
24** SID : 1.3
25** Last Modified : 11/6/98 10:33:43
26** Retrieved : 11/6/98 10:33:49
27**
28** ident @(#)rioinit.c 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32#ifdef SCCS_LABELS
33static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
34#endif
35
36#include <linux/config.h>
37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <asm/io.h>
41#include <asm/system.h>
42#include <asm/string.h>
43#include <asm/semaphore.h>
44#include <asm/uaccess.h>
45
46#include <linux/termios.h>
47#include <linux/serial.h>
48
49#include <linux/generic_serial.h>
50
51
52#include "linux_compat.h"
53#include "typdef.h"
54#include "pkt.h"
55#include "daemon.h"
56#include "rio.h"
57#include "riospace.h"
58#include "top.h"
59#include "cmdpkt.h"
60#include "map.h"
61#include "riotypes.h"
62#include "rup.h"
63#include "port.h"
64#include "riodrvr.h"
65#include "rioinfo.h"
66#include "func.h"
67#include "errors.h"
68#include "pci.h"
69
70#include "parmmap.h"
71#include "unixrup.h"
72#include "board.h"
73#include "host.h"
74#include "error.h"
75#include "phb.h"
76#include "link.h"
77#include "cmdblk.h"
78#include "route.h"
79#include "control.h"
80#include "cirrus.h"
81#include "rioioctl.h"
82#include "rio_linux.h"
83
84#undef bcopy
85#define bcopy rio_pcicopy
86
87int RIOPCIinit(struct rio_info *p, int Mode);
88
89#if 0
90static void RIOAllocateInterrupts(struct rio_info *);
91static int RIOReport(struct rio_info *);
92static void RIOStopInterrupts(struct rio_info *, int, int);
93#endif
94
95static int RIOScrub(int, BYTE *, int);
96
97#if 0
98extern int rio_intr();
99
100/*
101** Init time code.
102*/
103void
104rioinit( p, info )
105struct rio_info * p;
106struct RioHostInfo * info;
107{
108 /*
109 ** Multi-Host card support - taking the easy way out - sorry !
110 ** We allocate and set up the Host and Port structs when the
111 ** driver is called to 'install' the first host.
112 ** We check for this first 'call' by testing the RIOPortp pointer.
113 */
114 if ( !p->RIOPortp )
115 {
116 rio_dprintk (RIO_DEBUG_INIT, "Allocating and setting up driver data structures\n");
117
118 RIOAllocDataStructs(p); /* allocate host/port structs */
119 RIOSetupDataStructs(p); /* setup topology structs */
120 }
121
122 RIOInitHosts( p, info ); /* hunt down the hardware */
123
124 RIOAllocateInterrupts(p); /* allocate interrupts */
125 RIOReport(p); /* show what we found */
126}
127
128/*
129** Initialise the Cards
130*/
131void
132RIOInitHosts(p, info)
133struct rio_info * p;
134struct RioHostInfo * info;
135{
136/*
137** 15.10.1998 ARG - ESIL 0762 part fix
138** If there is no ISA card definition - we always look for PCI cards.
139** As we currently only support one host card this lets an ISA card
140** definition take precedence over PLUG and PLAY.
141** No ISA card - we are PLUG and PLAY with PCI.
142*/
143
144 /*
145 ** Note - for PCI both these will be zero, that's okay because
146 ** RIOPCIInit() fills them in if a card is found.
147 */
148 p->RIOHosts[p->RIONumHosts].Ivec = info->vector;
149 p->RIOHosts[p->RIONumHosts].PaddrP = info->location;
150
151 /*
152 ** Check that we are able to accommodate another host
153 */
154 if ( p->RIONumHosts >= RIO_HOSTS )
155 {
156 p->RIOFailed++;
157 return;
158 }
159
160 if ( info->bus & ISA_BUS )
161 {
162 rio_dprintk (RIO_DEBUG_INIT, "initialising card %d (ISA)\n", p->RIONumHosts);
163 RIOISAinit(p, p->mode);
164 }
165 else
166 {
167 rio_dprintk (RIO_DEBUG_INIT, "initialising card %d (PCI)\n", p->RIONumHosts);
168 RIOPCIinit(p, RIO_PCI_DEFAULT_MODE);
169 }
170
171 rio_dprintk (RIO_DEBUG_INIT, "Total hosts initialised so far : %d\n", p->RIONumHosts);
172
173
174#ifdef FUTURE_RELEASE
175 if (p->bus & EISA_BUS)
176 /* EISA card */
177 RIOEISAinit(p, RIO_EISA_DEFAULT_MODE);
178
179 if (p->bus & MCA_BUS)
180 /* MCA card */
181 RIOMCAinit(p, RIO_MCA_DEFAULT_MODE);
182#endif
183}
184
185/*
186** go through memory for an AT host that we pass in the device info
187** structure and initialise
188*/
189void
190RIOISAinit(p, mode)
191struct rio_info * p;
192int mode;
193{
194
195 /* XXX Need to implement this. */
196#if 0
197 p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
198 (int (*)())rio_intr, (char*)p->RIONumHosts);
199
200 rio_dprintk (RIO_DEBUG_INIT, "Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid );
201
202 if (RIODoAT(p, p->RIOHosts[p->RIONumHosts].PaddrP, mode)) {
203 return;
204 }
205 else {
206 rio_dprintk (RIO_DEBUG_INIT, "RIODoAT failed\n");
207 p->RIOFailed++;
208 }
209#endif
210
211}
212
213/*
214** RIODoAT :
215**
216** Map in a boards physical address, check that the board is there,
217** test the board and if everything is okay assign the board an entry
218** in the Rio Hosts structure.
219*/
220int
221RIODoAT(p, Base, mode)
222struct rio_info * p;
223int Base;
224int mode;
225{
226#define FOUND 1
227#define NOT_FOUND 0
228
229 caddr_t cardAddr;
230
231 /*
232 ** Check to see if we actually have a board at this physical address.
233 */
234 if ((cardAddr = RIOCheckForATCard(Base)) != 0) {
235 /*
236 ** Now test the board to see if it is working.
237 */
238 if (RIOBoardTest(Base, cardAddr, RIO_AT, 0) == RIO_SUCCESS) {
239 /*
240 ** Fill out a slot in the Rio host structure.
241 */
242 if (RIOAssignAT(p, Base, cardAddr, mode)) {
243 return(FOUND);
244 }
245 }
246 RIOMapout(Base, RIO_AT_MEM_SIZE, cardAddr);
247 }
248 return(NOT_FOUND);
249}
250
251caddr_t
252RIOCheckForATCard(Base)
253int Base;
254{
255 int off;
256 struct DpRam *cardp; /* (Points at the host) */
257 caddr_t virtAddr;
258 unsigned char RIOSigTab[24];
259/*
260** Table of values to search for as prom signature of a host card
261*/
262 strcpy(RIOSigTab, "JBJGPGGHINSMJPJR");
263
264 /*
265 ** Hey! Yes, You reading this code! Yo, grab a load a this:
266 **
267 ** IF the card is using WORD MODE rather than BYTE MODE
268 ** then it will occupy 128K of PHYSICAL memory area. So,
269 ** you might think that the following Mapin is wrong. Well,
270 ** it isn't, because the SECOND 64K of occupied space is an
271 ** EXACT COPY of the FIRST 64K. (good?), so, we need only
272 ** map it in in one 64K block.
273 */
274 if (RIOMapin(Base, RIO_AT_MEM_SIZE, &virtAddr) == -1) {
275 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't map the board in!\n");
276 return((caddr_t)0);
277 }
278
279 /*
280 ** virtAddr points to the DP ram of the system.
281 ** We now cast this to a pointer to a RIO Host,
282 ** and have a rummage about in the PROM.
283 */
284 cardp = (struct DpRam *)virtAddr;
285
286 for (off=0; RIOSigTab[off]; off++) {
287 if ((RBYTE(cardp->DpSignature[off]) & 0xFF) != RIOSigTab[off]) {
288 /*
289 ** Signature mismatch - card not at this address
290 */
291 RIOMapout(Base, RIO_AT_MEM_SIZE, virtAddr);
292 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't match the signature 0x%x 0x%x!\n",
293 (int)cardp, off);
294 return((caddr_t)0);
295 }
296 }
297
298 /*
299 ** If we get here then we must have found a valid board so return
300 ** its virtual address.
301 */
302 return(virtAddr);
303}
304#endif
305
306/**
307** RIOAssignAT :
308**
309** Fill out the fields in the p->RIOHosts structure now we know we know
310** we have a board present.
311**
312** bits < 0 indicates 8 bit operation requested,
313** bits > 0 indicates 16 bit operation.
314*/
315int
316RIOAssignAT(p, Base, virtAddr, mode)
317struct rio_info * p;
318int Base;
319caddr_t virtAddr;
320int mode;
321{
322 int bits;
323 struct DpRam *cardp = (struct DpRam *)virtAddr;
324
325 if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE))
326 bits = BYTE_OPERATION;
327 else
328 bits = WORD_OPERATION;
329
330 /*
331 ** Board has passed its scrub test. Fill in all the
332 ** transient stuff.
333 */
334 p->RIOHosts[p->RIONumHosts].Caddr = virtAddr;
335 p->RIOHosts[p->RIONumHosts].CardP = (struct DpRam *)virtAddr;
336
337 /*
338 ** Revision 01 AT host cards don't support WORD operations,
339 */
340 if ( RBYTE(cardp->DpRevision) == 01 )
341 bits = BYTE_OPERATION;
342
343 p->RIOHosts[p->RIONumHosts].Type = RIO_AT;
344 p->RIOHosts[p->RIONumHosts].Copy = bcopy;
345 /* set this later */
346 p->RIOHosts[p->RIONumHosts].Slot = -1;
347 p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits;
348 WBYTE(p->RIOHosts[p->RIONumHosts].Control,
349 BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
350 p->RIOHosts[p->RIONumHosts].Mode |
351 INTERRUPT_DISABLE );
352 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff);
353 WBYTE(p->RIOHosts[p->RIONumHosts].Control,
354 BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
355 p->RIOHosts[p->RIONumHosts].Mode |
356 INTERRUPT_DISABLE );
357 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff);
358 p->RIOHosts[p->RIONumHosts].UniqueNum =
359 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)|
360 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)|
361 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
362 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
363 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum);
364
365 p->RIONumHosts++;
366 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base);
367 return(1);
368}
369#if 0
370#ifdef FUTURE_RELEASE
371int RIOMCAinit(int Mode)
372{
373 uchar SlotNumber;
374 caddr_t Caddr;
375 uint Paddr;
376 uint Ivec;
377 int Handle;
378 int ret = 0;
379
380 /*
381 ** Valid mode information for MCA cards
382 ** is only FAST LINKS
383 */
384 Mode = (Mode & FAST_LINKS) ? McaTpFastLinks : McaTpSlowLinks;
385 rio_dprintk (RIO_DEBUG_INIT, "RIOMCAinit(%d)\n",Mode);
386
387
388 /*
389 ** Check out each of the slots
390 */
391 for (SlotNumber = 0; SlotNumber < McaMaxSlots; SlotNumber++) {
392 /*
393 ** Enable the slot we want to talk to
394 */
395 outb( McaSlotSelect, SlotNumber | McaSlotEnable );
396
397 /*
398 ** Read the ID word from the slot
399 */
400 if (((inb(McaIdHigh)<< 8)|inb(McaIdLow)) == McaRIOId)
401 {
402 rio_dprintk (RIO_DEBUG_INIT, "Potential MCA card in slot %d\n", SlotNumber);
403
404 /*
405 ** Card appears to be a RIO MCA card!
406 */
407 RIOMachineType |= (1<<RIO_MCA);
408
409 /*
410 ** Just check we haven't found too many wonderful objects
411 */
412 if ( RIONumHosts >= RIO_HOSTS )
413 {
414 Rprintf(RIOMesgTooManyCards);
415 return(ret);
416 }
417
418 /*
419 ** McaIrqEnable contains the interrupt vector, and a card
420 ** enable bit.
421 */
422 Ivec = inb(McaIrqEnable);
423
424 rio_dprintk (RIO_DEBUG_INIT, "Ivec is %x\n", Ivec);
425
426 switch ( Ivec & McaIrqMask )
427 {
428 case McaIrq9:
429 rio_dprintk (RIO_DEBUG_INIT, "IRQ9\n");
430 break;
431 case McaIrq3:
432 rio_dprintk (RIO_DEBUG_INIT, "IRQ3\n");
433 break;
434 case McaIrq4:
435 rio_dprintk (RIO_DEBUG_INIT, "IRQ4\n");
436 break;
437 case McaIrq7:
438 rio_dprintk (RIO_DEBUG_INIT, "IRQ7\n");
439 break;
440 case McaIrq10:
441 rio_dprintk (RIO_DEBUG_INIT, "IRQ10\n");
442 break;
443 case McaIrq11:
444 rio_dprintk (RIO_DEBUG_INIT, "IRQ11\n");
445 break;
446 case McaIrq12:
447 rio_dprintk (RIO_DEBUG_INIT, "IRQ12\n");
448 break;
449 case McaIrq15:
450 rio_dprintk (RIO_DEBUG_INIT, "IRQ15\n");
451 break;
452 }
453
454 /*
455 ** If the card enable bit isn't set, then set it!
456 */
457 if ((Ivec & McaCardEnable) != McaCardEnable) {
458 rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable not set - setting!\n");
459 outb(McaIrqEnable,Ivec|McaCardEnable);
460 } else
461 rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable already set\n");
462
463 /*
464 ** Convert the IRQ enable mask into something useful
465 */
466 Ivec = RIOMcaToIvec[Ivec & McaIrqMask];
467
468 /*
469 ** Find the physical address
470 */
471 rio_dprintk (RIO_DEBUG_INIT, "inb(McaMemory) is %x\n", inb(McaMemory));
472 Paddr = McaAddress(inb(McaMemory));
473
474 rio_dprintk (RIO_DEBUG_INIT, "MCA card has Ivec %d Addr %x\n", Ivec, Paddr);
475
476 if ( Paddr != 0 )
477 {
478
479 /*
480 ** Tell the memory mapper that we want to talk to it
481 */
482 Handle = RIOMapin( Paddr, RIO_MCA_MEM_SIZE, &Caddr );
483
484 if ( Handle == -1 ) {
485 rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE, Paddr;
486 continue;
487 }
488
489 rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
490
491 /*
492 ** And check that it is actually there!
493 */
494 if ( RIOBoardTest( Paddr,Caddr,RIO_MCA,SlotNumber ) == RIO_SUCCESS )
495 {
496 rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
497 rio_dprintk (RIO_DEBUG_INIT, "Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
498 SlotNumber, RIO_MCA, Paddr, Caddr, Mode);
499
500 /*
501 ** Board has passed its scrub test. Fill in all the
502 ** transient stuff.
503 */
504 p->RIOHosts[RIONumHosts].Slot = SlotNumber;
505 p->RIOHosts[RIONumHosts].Ivec = Ivec;
506 p->RIOHosts[RIONumHosts].Type = RIO_MCA;
507 p->RIOHosts[RIONumHosts].Copy = bcopy;
508 p->RIOHosts[RIONumHosts].PaddrP = Paddr;
509 p->RIOHosts[RIONumHosts].Caddr = Caddr;
510 p->RIOHosts[RIONumHosts].CardP = (struct DpRam *)Caddr;
511 p->RIOHosts[RIONumHosts].Mode = Mode;
512 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt , 0xff);
513 p->RIOHosts[RIONumHosts].UniqueNum =
514 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[0])&0xFF)<<0)|
515 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[1])&0xFF)<<8)|
516 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[2])&0xFF)<<16)|
517 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[3])&0xFF)<<24);
518 RIONumHosts++;
519 ret++;
520 }
521 else
522 {
523 /*
524 ** It failed the test, so ignore it.
525 */
526 rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
527 RIOMapout(Paddr, RIO_MCA_MEM_SIZE, Caddr );
528 }
529 }
530 else
531 {
532 rio_dprintk (RIO_DEBUG_INIT, "Slot %d - Paddr zero!\n", SlotNumber);
533 }
534 }
535 else
536 {
537 rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
538 }
539 }
540 /*
541 ** Now we have checked all the slots, turn off the MCA slot selector
542 */
543 outb(McaSlotSelect,0);
544 rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
545 return ret;
546}
547
548int RIOEISAinit( int Mode )
549{
550 static int EISADone = 0;
551 uint Paddr;
552 int PollIntMixMsgDone = 0;
553 caddr_t Caddr;
554 ushort Ident;
555 uchar EisaSlot;
556 uchar Ivec;
557 int ret = 0;
558
559 /*
560 ** The only valid mode information for EISA hosts is fast or slow
561 ** links.
562 */
563 Mode = (Mode & FAST_LINKS) ? EISA_TP_FAST_LINKS : EISA_TP_SLOW_LINKS;
564
565 if ( EISADone )
566 {
567 rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit() - already done, return.\n");
568 return(0);
569 }
570
571 EISADone++;
572
573 rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit()\n");
574
575
576 /*
577 ** First check all cards to see if ANY are set for polled mode operation.
578 ** If so, set ALL to polled.
579 */
580
581 for ( EisaSlot=1; EisaSlot<=RIO_MAX_EISA_SLOTS; EisaSlot++ )
582 {
583 Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) |
584 INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO);
585
586 if ( Ident == RIO_EISA_IDENT )
587 {
588 rio_dprintk (RIO_DEBUG_INIT, "Found Specialix product\n");
589
590 if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE )
591 {
592 rio_dprintk (RIO_DEBUG_INIT, "Not Specialix RIO - Product number %x\n",
593 INBZ(EisaSlot, EISA_PRODUCT_NUMBER));
594 continue; /* next slot */
595 }
596 /*
597 ** Its a Specialix RIO!
598 */
599 rio_dprintk (RIO_DEBUG_INIT, "RIO Revision %d\n",
600 INBZ(EisaSlot, EISA_REVISION_NUMBER));
601
602 RIOMachineType |= (1<<RIO_EISA);
603
604 /*
605 ** Just check we haven't found too many wonderful objects
606 */
607 if ( RIONumHosts >= RIO_HOSTS )
608 {
609 Rprintf(RIOMesgTooManyCards);
610 return 0;
611 }
612
613 /*
614 ** Ensure that the enable bit is set!
615 */
616 OUTBZ( EisaSlot, EISA_ENABLE, RIO_EISA_ENABLE_BIT );
617
618 /*
619 ** EISA_INTERRUPT_VEC contains the interrupt vector.
620 */
621 Ivec = INBZ(EisaSlot,EISA_INTERRUPT_VEC);
622
623#ifdef RIODEBUG
624 switch ( Ivec & EISA_INTERRUPT_MASK )
625 {
626 case EISA_IRQ_3:
627 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 3\n");
628 break;
629 case EISA_IRQ_4:
630 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 4\n");
631 break;
632 case EISA_IRQ_5:
633 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 5\n");
634 break;
635 case EISA_IRQ_6:
636 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 6\n");
637 break;
638 case EISA_IRQ_7:
639 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 7\n");
640 break;
641 case EISA_IRQ_9:
642 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 9\n");
643 break;
644 case EISA_IRQ_10:
645 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 10\n");
646 break;
647 case EISA_IRQ_11:
648 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 11\n");
649 break;
650 case EISA_IRQ_12:
651 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 12\n");
652 break;
653 case EISA_IRQ_14:
654 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 14\n");
655 break;
656 case EISA_IRQ_15:
657 rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 15\n");
658 break;
659 case EISA_POLLED:
660 rio_dprintk (RIO_DEBUG_INIT, "EISA POLLED\n");
661 break;
662 default:
663 rio_dprintk (RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
664 Ivec &= EISA_CONTROL_MASK;
665 }
666#endif
667
668 if ( (Ivec & EISA_INTERRUPT_MASK) ==
669 EISA_POLLED )
670 {
671 RIOWillPoll = 1;
672 break; /* From EisaSlot loop */
673 }
674 }
675 }
676
677 /*
678 ** Do it all again now we know whether to change all cards to polled
679 ** mode or not
680 */
681
682 for ( EisaSlot=1; EisaSlot<=RIO_MAX_EISA_SLOTS; EisaSlot++ )
683 {
684 Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) |
685 INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO);
686
687 if ( Ident == RIO_EISA_IDENT )
688 {
689 if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE )
690 continue; /* next slot */
691
692 /*
693 ** Its a Specialix RIO!
694 */
695
696 /*
697 ** Ensure that the enable bit is set!
698 */
699 OUTBZ( EisaSlot, EISA_ENABLE, RIO_EISA_ENABLE_BIT );
700
701 /*
702 ** EISA_INTERRUPT_VEC contains the interrupt vector.
703 */
704 Ivec = INBZ(EisaSlot,EISA_INTERRUPT_VEC);
705
706 if ( RIOWillPoll )
707 {
708 /*
709 ** If we are going to operate in polled mode, but this
710 ** board is configured to be interrupt driven, display
711 ** the message explaining the situation to the punter,
712 ** assuming we haven't already done so.
713 */
714
715 if ( !PollIntMixMsgDone &&
716 (Ivec & EISA_INTERRUPT_MASK) != EISA_POLLED )
717 {
718 Rprintf(RIOMesgAllPolled);
719 PollIntMixMsgDone = 1;
720 }
721
722 /*
723 ** Ungraciously ignore whatever the board reports as its
724 ** interrupt vector...
725 */
726
727 Ivec &= ~EISA_INTERRUPT_MASK;
728
729 /*
730 ** ...and force it to dance to the poll tune.
731 */
732
733 Ivec |= EISA_POLLED;
734 }
735
736 /*
737 ** Convert the IRQ enable mask into something useful (0-15)
738 */
739 Ivec = RIOEisaToIvec(Ivec);
740
741 rio_dprintk (RIO_DEBUG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
742 EisaSlot, Ivec);
743
744 /*
745 ** Find the physical address
746 */
747 Paddr = (INBZ(EisaSlot,EISA_MEMORY_BASE_HI)<<24) |
748 (INBZ(EisaSlot,EISA_MEMORY_BASE_LO)<<16);
749
750 rio_dprintk (RIO_DEBUG_INIT, "EISA card has Ivec %d Addr %x\n", Ivec, Paddr);
751
752 if ( Paddr == 0 )
753 {
754 rio_dprintk (RIO_DEBUG_INIT,
755 "Board in slot %d configured for address zero!\n", EisaSlot);
756 continue;
757 }
758
759 /*
760 ** Tell the memory mapper that we want to talk to it
761 */
762 rio_dprintk (RIO_DEBUG_INIT, "About to map EISA card \n");
763
764 if (RIOMapin( Paddr, RIO_EISA_MEM_SIZE, &Caddr) == -1) {
765 rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n",
766 RIO_EISA_MEM_SIZE,Paddr);
767 continue;
768 }
769
770 rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
771
772 /*
773 ** And check that it is actually there!
774 */
775 if ( RIOBoardTest( Paddr,Caddr,RIO_EISA,EisaSlot) == RIO_SUCCESS )
776 {
777 rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
778 rio_dprintk (RIO_DEBUG_INIT,
779 "Slot %d. Ivec %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
780 EisaSlot,Ivec,RIO_EISA,Paddr,Caddr,Mode);
781
782 /*
783 ** Board has passed its scrub test. Fill in all the
784 ** transient stuff.
785 */
786 p->RIOHosts[RIONumHosts].Slot = EisaSlot;
787 p->RIOHosts[RIONumHosts].Ivec = Ivec;
788 p->RIOHosts[RIONumHosts].Type = RIO_EISA;
789 p->RIOHosts[RIONumHosts].Copy = bcopy;
790 p->RIOHosts[RIONumHosts].PaddrP = Paddr;
791 p->RIOHosts[RIONumHosts].Caddr = Caddr;
792 p->RIOHosts[RIONumHosts].CardP = (struct DpRam *)Caddr;
793 p->RIOHosts[RIONumHosts].Mode = Mode;
794 /*
795 ** because the EISA prom is mapped into IO space, we
796 ** need to copy the unqiue number into the memory area
797 ** that it would have occupied, so that the download
798 ** code can determine its ID and card type.
799 */
800 WBYTE(p->RIOHosts[RIONumHosts].Unique[0],INBZ(EisaSlot,EISA_UNIQUE_NUM_0));
801 WBYTE(p->RIOHosts[RIONumHosts].Unique[1],INBZ(EisaSlot,EISA_UNIQUE_NUM_1));
802 WBYTE(p->RIOHosts[RIONumHosts].Unique[2],INBZ(EisaSlot,EISA_UNIQUE_NUM_2));
803 WBYTE(p->RIOHosts[RIONumHosts].Unique[3],INBZ(EisaSlot,EISA_UNIQUE_NUM_3));
804 p->RIOHosts[RIONumHosts].UniqueNum =
805 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[0])&0xFF)<<0)|
806 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[1])&0xFF)<<8)|
807 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[2])&0xFF)<<16)|
808 ((RBYTE(p->RIOHosts[RIONumHosts].Unique[3])&0xFF)<<24);
809 INBZ(EisaSlot,EISA_INTERRUPT_RESET);
810 RIONumHosts++;
811 ret++;
812 }
813 else
814 {
815 /*
816 ** It failed the test, so ignore it.
817 */
818 rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
819
820 RIOMapout(Paddr, RIO_EISA_MEM_SIZE, Caddr );
821 }
822 }
823 }
824 if (RIOMachineType & RIO_EISA)
825 return ret+1;
826 return ret;
827}
828#endif
829
830
831#ifndef linux
832
833#define CONFIG_ADDRESS 0xcf8
834#define CONFIG_DATA 0xcfc
835#define FORWARD_REG 0xcfa
836
837
838static int
839read_config(int bus_number, int device_num, int r_number)
840{
841 unsigned int cav;
842 unsigned int val;
843
844/*
845 Build config_address_value:
846
847 31 24 23 16 15 11 10 8 7 0
848 ------------------------------------------------------
849 |1| 0000000 | bus_number | device # | 000 | register |
850 ------------------------------------------------------
851*/
852
853 cav = r_number & 0xff;
854 cav |= ((device_num & 0x1f) << 11);
855 cav |= ((bus_number & 0xff) << 16);
856 cav |= 0x80000000; /* Enable bit */
857 outpd(CONFIG_ADDRESS,cav);
858 val = inpd(CONFIG_DATA);
859 outpd(CONFIG_ADDRESS,0);
860 return val;
861}
862
863static
864write_config(bus_number,device_num,r_number,val)
865{
866 unsigned int cav;
867
868/*
869 Build config_address_value:
870
871 31 24 23 16 15 11 10 8 7 0
872 ------------------------------------------------------
873 |1| 0000000 | bus_number | device # | 000 | register |
874 ------------------------------------------------------
875*/
876
877 cav = r_number & 0xff;
878 cav |= ((device_num & 0x1f) << 11);
879 cav |= ((bus_number & 0xff) << 16);
880 cav |= 0x80000000; /* Enable bit */
881 outpd(CONFIG_ADDRESS, cav);
882 outpd(CONFIG_DATA, val);
883 outpd(CONFIG_ADDRESS, 0);
884 return val;
885}
886#else
887/* XXX Implement these... */
888static int
889read_config(int bus_number, int device_num, int r_number)
890{
891 return 0;
892}
893
894static int
895write_config(int bus_number, int device_num, int r_number)
896{
897 return 0;
898}
899
900#endif
901
902int
903RIOPCIinit(p, Mode)
904struct rio_info *p;
905int Mode;
906{
907 #define MAX_PCI_SLOT 32
908 #define RIO_PCI_JET_CARD 0x200011CB
909
910 static int slot; /* count of machine's PCI slots searched so far */
911 caddr_t Caddr; /* Virtual address of the current PCI host card. */
912 unsigned char Ivec; /* interrupt vector for the current PCI host */
913 unsigned long Paddr; /* Physical address for the current PCI host */
914 int Handle; /* Handle to Virtual memory allocated for current PCI host */
915
916
917 rio_dprintk (RIO_DEBUG_INIT, "Search for a RIO PCI card - start at slot %d\n", slot);
918
919 /*
920 ** Initialise the search status
921 */
922 p->RIOLastPCISearch = RIO_FAIL;
923
924 while ( (slot < MAX_PCI_SLOT) & (p->RIOLastPCISearch != RIO_SUCCESS) )
925 {
926 rio_dprintk (RIO_DEBUG_INIT, "Currently testing slot %d\n", slot);
927
928 if (read_config(0,slot,0) == RIO_PCI_JET_CARD) {
929 p->RIOHosts[p->RIONumHosts].Ivec = 0;
930 Paddr = read_config(0,slot,0x18);
931 Paddr = Paddr - (Paddr & 0x1); /* Mask off the io bit */
932
933 if ( (Paddr == 0) || ((Paddr & 0xffff0000) == 0xffff0000) ) {
934 rio_dprintk (RIO_DEBUG_INIT, "Goofed up slot\n"); /* what! */
935 slot++;
936 continue;
937 }
938
939 p->RIOHosts[p->RIONumHosts].PaddrP = Paddr;
940 Ivec = (read_config(0,slot,0x3c) & 0xff);
941
942 rio_dprintk (RIO_DEBUG_INIT, "PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec);
943
944 Handle = RIOMapin( Paddr, RIO_PCI_MEM_SIZE, &Caddr );
945 if (Handle == -1) {
946 rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr);
947 slot++;
948 continue;
949 }
950 p->RIOHosts[p->RIONumHosts].Ivec = Ivec + 32;
951 p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
952 (int (*)())rio_intr, (char *)p->RIONumHosts);
953 if (RIOBoardTest( Paddr, Caddr, RIO_PCI, 0 ) == RIO_SUCCESS) {
954 rio_dprintk (RIO_DEBUG_INIT, ("Board has passed test\n");
955 rio_dprintk (RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, Mode);
956
957 /*
958 ** Board has passed its scrub test. Fill in all the
959 ** transient stuff.
960 */
961 p->RIOHosts[p->RIONumHosts].Slot = 0;
962 p->RIOHosts[p->RIONumHosts].Ivec = Ivec + 32;
963 p->RIOHosts[p->RIONumHosts].Type = RIO_PCI;
964 p->RIOHosts[p->RIONumHosts].Copy = rio_pcicopy;
965 p->RIOHosts[p->RIONumHosts].PaddrP = Paddr;
966 p->RIOHosts[p->RIONumHosts].Caddr = Caddr;
967 p->RIOHosts[p->RIONumHosts].CardP = (struct DpRam *)Caddr;
968 p->RIOHosts[p->RIONumHosts].Mode = Mode;
969
970#if 0
971 WBYTE(p->RIOHosts[p->RIONumHosts].Control,
972 BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
973 p->RIOHosts[p->RIONumHosts].Mode |
974 INTERRUPT_DISABLE );
975 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff);
976 WBYTE(p->RIOHosts[p->RIONumHosts].Control,
977 BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
978 p->RIOHosts[p->RIONumHosts].Mode |
979 INTERRUPT_DISABLE );
980 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff);
981#else
982 WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
983#endif
984 p->RIOHosts[p->RIONumHosts].UniqueNum =
985 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)|
986 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)|
987 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
988 ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
989
990 rio_dprintk (RIO_DEBUG_INIT, "Unique no 0x%x.\n",
991 p->RIOHosts[p->RIONumHosts].UniqueNum);
992
993 p->RIOLastPCISearch = RIO_SUCCESS;
994 p->RIONumHosts++;
995 }
996 }
997 slot++;
998 }
999
1000 if ( slot >= MAX_PCI_SLOT ) {
1001 rio_dprintk (RIO_DEBUG_INIT, "All %d PCI slots have tested for RIO cards !!!\n",
1002 MAX_PCI_SLOT);
1003 }
1004
1005
1006 /*
1007 ** I don't think we want to do this anymore
1008 **
1009
1010 if (!p->RIOLastPCISearch == RIO_FAIL ) {
1011 p->RIOFailed++;
1012 }
1013
1014 **
1015 */
1016}
1017
1018#ifdef FUTURE_RELEASE
1019void riohalt( void )
1020{
1021 int host;
1022 for ( host=0; host<p->RIONumHosts; host++ )
1023 {
1024 rio_dprintk (RIO_DEBUG_INIT, "Stop host %d\n", host);
1025 (void)RIOBoardTest( p->RIOHosts[host].PaddrP, p->RIOHosts[host].Caddr, p->RIOHosts[host].Type,p->RIOHosts[host].Slot );
1026 }
1027}
1028#endif
1029#endif
1030
1031static uchar val[] = {
1032#ifdef VERY_LONG_TEST
1033 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
1034 0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36,
1035#endif
1036 0xff, 0x00, 0x00 };
1037
1038#define TEST_END sizeof(val)
1039
1040/*
1041** RAM test a board.
1042** Nothing too complicated, just enough to check it out.
1043*/
1044int
1045RIOBoardTest(paddr, caddr, type, slot)
1046paddr_t paddr;
1047caddr_t caddr;
1048uchar type;
1049int slot;
1050{
1051 struct DpRam *DpRam = (struct DpRam *)caddr;
1052 char *ram[4];
1053 int size[4];
1054 int op, bank;
1055 int nbanks;
1056
1057 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
1058 type,(int)DpRam, slot);
1059
1060 RIOHostReset(type, DpRam, slot);
1061
1062 /*
1063 ** Scrub the memory. This comes in several banks:
1064 ** DPsram1 - 7000h bytes
1065 ** DPsram2 - 200h bytes
1066 ** DPsram3 - 7000h bytes
1067 ** scratch - 1000h bytes
1068 */
1069
1070 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n");
1071
1072 size[0] = DP_SRAM1_SIZE;
1073 size[1] = DP_SRAM2_SIZE;
1074 size[2] = DP_SRAM3_SIZE;
1075 size[3] = DP_SCRATCH_SIZE;
1076
1077 ram[0] = (char *)&DpRam->DpSram1[0];
1078 ram[1] = (char *)&DpRam->DpSram2[0];
1079 ram[2] = (char *)&DpRam->DpSram3[0];
1080 nbanks = (type == RIO_PCI) ? 3 : 4;
1081 if (nbanks == 4)
1082 ram[3] = (char *)&DpRam->DpScratch[0];
1083
1084
1085 if (nbanks == 3) {
1086 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
1087 (int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]);
1088 } else {
1089 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
1090 (int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2], (int)ram[3],
1091 size[3]);
1092 }
1093
1094 /*
1095 ** This scrub operation will test for crosstalk between
1096 ** banks. TEST_END is a magic number, and relates to the offset
1097 ** within the 'val' array used by Scrub.
1098 */
1099 for (op=0; op<TEST_END; op++) {
1100 for (bank=0; bank<nbanks; bank++) {
1101 if (RIOScrub(op, (BYTE *)ram[bank], size[bank]) == RIO_FAIL) {
1102 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n",
1103 bank, op);
1104 return RIO_FAIL;
1105 }
1106 }
1107 }
1108
1109 rio_dprintk (RIO_DEBUG_INIT, "Test completed\n");
1110 return RIO_SUCCESS;
1111}
1112
1113
1114/*
1115** Scrub an area of RAM.
1116** Define PRETEST and POSTTEST for a more thorough checking of the
1117** state of the memory.
1118** Call with op set to an index into the above 'val' array to determine
1119** which value will be written into memory.
1120** Call with op set to zero means that the RAM will not be read and checked
1121** before it is written.
1122** Call with op not zero, and the RAM will be read and compated with val[op-1]
1123** to check that the data from the previous phase was retained.
1124*/
1125static int
1126RIOScrub(op, ram, size)
1127int op;
1128BYTE * ram;
1129int size;
1130{
1131 int off;
1132 unsigned char oldbyte;
1133 unsigned char newbyte;
1134 unsigned char invbyte;
1135 unsigned short oldword;
1136 unsigned short newword;
1137 unsigned short invword;
1138 unsigned short swapword;
1139
1140 if (op) {
1141 oldbyte = val[op-1];
1142 oldword = oldbyte | (oldbyte<<8);
1143 } else
1144 oldbyte = oldword = 0; /* Tell the compiler we've initilalized them. */
1145 newbyte = val[op];
1146 newword = newbyte | (newbyte<<8);
1147 invbyte = ~newbyte;
1148 invword = invbyte | (invbyte<<8);
1149
1150 /*
1151 ** Check that the RAM contains the value that should have been left there
1152 ** by the previous test (not applicable for pass zero)
1153 */
1154 if (op) {
1155 for (off=0; off<size; off++) {
1156 if (RBYTE(ram[off]) != oldbyte) {
1157 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
1158 return RIO_FAIL;
1159 }
1160 }
1161 for (off=0; off<size; off+=2) {
1162 if (*(ushort *)&ram[off] != oldword) {
1163 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]);
1164 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
1165 return RIO_FAIL;
1166 }
1167 }
1168 }
1169
1170 /*
1171 ** Now write the INVERSE of the test data into every location, using
1172 ** BYTE write operations, first checking before each byte is written
1173 ** that the location contains the old value still, and checking after
1174 ** the write that the location contains the data specified - this is
1175 ** the BYTE read/write test.
1176 */
1177 for (off=0; off<size; off++) {
1178 if (op && (RBYTE(ram[off]) != oldbyte)) {
1179 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
1180 return RIO_FAIL;
1181 }
1182 WBYTE(ram[off],invbyte);
1183 if (RBYTE(ram[off]) != invbyte) {
1184 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, RBYTE(ram[off]));
1185 return RIO_FAIL;
1186 }
1187 }
1188
1189 /*
1190 ** now, use WORD operations to write the test value into every location,
1191 ** check as before that the location contains the previous test value
1192 ** before overwriting, and that it contains the data value written
1193 ** afterwards.
1194 ** This is the WORD operation test.
1195 */
1196 for (off=0; off<size; off+=2) {
1197 if (*(ushort *)&ram[off] != invword) {
1198 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, *(ushort *)&ram[off]);
1199 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
1200 return RIO_FAIL;
1201 }
1202
1203 *(ushort *)&ram[off] = newword;
1204 if ( *(ushort *)&ram[off] != newword ) {
1205 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
1206 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
1207 return RIO_FAIL;
1208 }
1209 }
1210
1211 /*
1212 ** now run through the block of memory again, first in byte mode
1213 ** then in word mode, and check that all the locations contain the
1214 ** required test data.
1215 */
1216 for (off=0; off<size; off++) {
1217 if (RBYTE(ram[off]) != newbyte) {
1218 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
1219 return RIO_FAIL;
1220 }
1221 }
1222
1223 for (off=0; off<size; off+=2) {
1224 if ( *(ushort *)&ram[off] != newword ) {
1225 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
1226 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
1227 return RIO_FAIL;
1228 }
1229 }
1230
1231 /*
1232 ** time to check out byte swapping errors
1233 */
1234 swapword = invbyte | (newbyte << 8);
1235
1236 for (off=0; off<size; off+=2) {
1237 WBYTE(ram[off],invbyte);
1238 WBYTE(ram[off+1],newbyte);
1239 }
1240
1241 for ( off=0; off<size; off+=2 ) {
1242 if (*(ushort *)&ram[off] != swapword) {
1243 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, *((ushort *)&ram[off]));
1244 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
1245 return RIO_FAIL;
1246 }
1247 *((ushort *)&ram[off]) = ~swapword;
1248 }
1249
1250 for (off=0; off<size; off+=2) {
1251 if (RBYTE(ram[off]) != newbyte) {
1252 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
1253 return RIO_FAIL;
1254 }
1255 if (RBYTE(ram[off+1]) != invbyte) {
1256 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, RBYTE(ram[off+1]));
1257 return RIO_FAIL;
1258 }
1259 *((ushort *)&ram[off]) = newword;
1260 }
1261 return RIO_SUCCESS;
1262}
1263
1264/*
1265** try to ensure that every host is either in polled mode
1266** or is in interrupt mode. Only allow interrupt mode if
1267** all hosts can interrupt (why?)
1268** and force into polled mode if told to. Patch up the
1269** interrupt vector & salute The Queen when you've done.
1270*/
1271#if 0
1272static void
1273RIOAllocateInterrupts(p)
1274struct rio_info * p;
1275{
1276 int Host;
1277
1278 /*
1279 ** Easy case - if we have been told to poll, then we poll.
1280 */
1281 if (p->mode & POLLED_MODE) {
1282 RIOStopInterrupts(p, 0, 0);
1283 return;
1284 }
1285
1286 /*
1287 ** check - if any host has been set to polled mode, then all must be.
1288 */
1289 for (Host=0; Host<p->RIONumHosts; Host++) {
1290 if ( (p->RIOHosts[Host].Type != RIO_AT) &&
1291 (p->RIOHosts[Host].Ivec == POLLED) ) {
1292 RIOStopInterrupts(p, 1, Host );
1293 return;
1294 }
1295 }
1296 for (Host=0; Host<p->RIONumHosts; Host++) {
1297 if (p->RIOHosts[Host].Type == RIO_AT) {
1298 if ( (p->RIOHosts[Host].Ivec - 32) == 0) {
1299 RIOStopInterrupts(p, 2, Host );
1300 return;
1301 }
1302 }
1303 }
1304}
1305
1306/*
1307** something has decided that we can't be doing with these
1308** new-fangled interrupt thingies. Set everything up to just
1309** poll.
1310*/
1311static void
1312RIOStopInterrupts(p, Reason, Host)
1313struct rio_info * p;
1314int Reason;
1315int Host;
1316{
1317#ifdef FUTURE_RELEASE
1318 switch (Reason) {
1319 case 0: /* forced into polling by rio_polled */
1320 break;
1321 case 1: /* SCU has set 'Host' into polled mode */
1322 break;
1323 case 2: /* there aren't enough interrupt vectors for 'Host' */
1324 break;
1325 }
1326#endif
1327
1328 for (Host=0; Host<p->RIONumHosts; Host++ ) {
1329 struct Host *HostP = &p->RIOHosts[Host];
1330
1331 switch (HostP->Type) {
1332 case RIO_AT:
1333 /*
1334 ** The AT host has it's interrupts disabled by clearing the
1335 ** int_enable bit.
1336 */
1337 HostP->Mode &= ~INTERRUPT_ENABLE;
1338 HostP->Ivec = POLLED;
1339 break;
1340#ifdef FUTURE_RELEASE
1341 case RIO_EISA:
1342 /*
1343 ** The EISA host has it's interrupts disabled by setting the
1344 ** Ivec to zero
1345 */
1346 HostP->Ivec = POLLED;
1347 break;
1348#endif
1349 case RIO_PCI:
1350 /*
1351 ** The PCI host has it's interrupts disabled by clearing the
1352 ** int_enable bit, like a regular host card.
1353 */
1354 HostP->Mode &= ~RIO_PCI_INT_ENABLE;
1355 HostP->Ivec = POLLED;
1356 break;
1357#ifdef FUTURE_RELEASE
1358 case RIO_MCA:
1359 /*
1360 ** There's always one, isn't there?
1361 ** The MCA host card cannot have it's interrupts disabled.
1362 */
1363 RIOPatchVec(HostP);
1364 break;
1365#endif
1366 }
1367 }
1368}
1369
1370/*
1371** This function is called at init time to setup the data structures.
1372*/
1373void
1374RIOAllocDataStructs(p)
1375struct rio_info * p;
1376{
1377 int port,
1378 host,
1379 tm;
1380
1381 p->RIOPortp = (struct Port *)sysbrk(RIO_PORTS * sizeof(struct Port));
1382 if (!p->RIOPortp) {
1383 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for port structures\n");
1384 p->RIOFailed++;
1385 return;
1386 }
1387 bzero( p->RIOPortp, sizeof(struct Port) * RIO_PORTS );
1388 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: allocated and cleared memory for port structs\n");
1389 rio_dprintk (RIO_DEBUG_INIT, "First RIO port struct @0x%x, size=0x%x bytes\n",
1390 (int)p->RIOPortp, sizeof(struct Port));
1391
1392 for( port=0; port<RIO_PORTS; port++ ) {
1393 p->RIOPortp[port].PortNum = port;
1394 p->RIOPortp[port].TtyP = &p->channel[port];
1395 sreset (p->RIOPortp[port].InUse); /* Let the first guy uses it */
1396 p->RIOPortp[port].portSem = -1; /* Let the first guy takes it */
1397 p->RIOPortp[port].ParamSem = -1; /* Let the first guy takes it */
1398 p->RIOPortp[port].timeout_id = 0; /* Let the first guy takes it */
1399 }
1400
1401 p->RIOHosts = (struct Host *)sysbrk(RIO_HOSTS * sizeof(struct Host));
1402 if (!p->RIOHosts) {
1403 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for host structures\n");
1404 p->RIOFailed++;
1405 return;
1406 }
1407 bzero(p->RIOHosts, sizeof(struct Host)*RIO_HOSTS);
1408 rio_dprintk (RIO_DEBUG_INIT, "RIO-init: allocated and cleared memory for host structs\n");
1409 rio_dprintk (RIO_DEBUG_INIT, "First RIO host struct @0x%x, size=0x%x bytes\n",
1410 (int)p->RIOHosts, sizeof(struct Host));
1411
1412 for( host=0; host<RIO_HOSTS; host++ ) {
1413 spin_lock_init (&p->RIOHosts[host].HostLock);
1414 p->RIOHosts[host].timeout_id = 0; /* Let the first guy takes it */
1415 }
1416 /*
1417 ** check that the buffer size is valid, round down to the next power of
1418 ** two if necessary; if the result is zero, then, hey, no double buffers.
1419 */
1420 for ( tm = 1; tm && tm <= p->RIOConf.BufferSize; tm <<= 1 )
1421 ;
1422 tm >>= 1;
1423 p->RIOBufferSize = tm;
1424 p->RIOBufferMask = tm ? tm - 1 : 0;
1425}
1426
1427/*
1428** this function gets called whenever the data structures need to be
1429** re-setup, for example, after a riohalt (why did I ever invent it?)
1430*/
1431void
1432RIOSetupDataStructs(p)
1433struct rio_info * p;
1434{
1435 int host, entry, rup;
1436
1437 for ( host=0; host<RIO_HOSTS; host++ ) {
1438 struct Host *HostP = &p->RIOHosts[host];
1439 for ( entry=0; entry<LINKS_PER_UNIT; entry++ ) {
1440 HostP->Topology[entry].Unit = ROUTE_DISCONNECT;
1441 HostP->Topology[entry].Link = NO_LINK;
1442 }
1443 bcopy("HOST X", HostP->Name, 7);
1444 HostP->Name[5] = '1'+host;
1445 for (rup=0; rup<(MAX_RUP + LINKS_PER_UNIT); rup++) {
1446 if (rup < MAX_RUP) {
1447 for (entry=0; entry<LINKS_PER_UNIT; entry++ ) {
1448 HostP->Mapping[rup].Topology[entry].Unit = ROUTE_DISCONNECT;
1449 HostP->Mapping[rup].Topology[entry].Link = NO_LINK;
1450 }
1451 RIODefaultName(p, HostP, rup);
1452 }
1453 spin_lock_init(&HostP->UnixRups[rup].RupLock);
1454 }
1455 }
1456}
1457#endif
1458
1459int
1460RIODefaultName(p, HostP, UnitId)
1461struct rio_info * p;
1462struct Host * HostP;
1463uint UnitId;
1464{
1465#ifdef CHECK
1466 CheckHost( Host );
1467 CheckUnitId( UnitId );
1468#endif
1469 bcopy("UNKNOWN RTA X-XX",HostP->Mapping[UnitId].Name,17);
1470 HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts);
1471 if ((UnitId+1) > 9) {
1472 HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10);
1473 HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10);
1474 }
1475 else {
1476 HostP->Mapping[UnitId].Name[14]='1'+UnitId;
1477 HostP->Mapping[UnitId].Name[15]=0;
1478 }
1479 return 0;
1480}
1481
1482#define RIO_RELEASE "Linux"
1483#define RELEASE_ID "1.0"
1484
1485#if 0
1486static int
1487RIOReport(p)
1488struct rio_info * p;
1489{
1490 char * RIORelease = RIO_RELEASE;
1491 char * RIORelID = RELEASE_ID;
1492 int host;
1493
1494 rio_dprintk (RIO_DEBUG_INIT, "RIO : Release: %s ID: %s\n", RIORelease, RIORelID);
1495
1496 if ( p->RIONumHosts==0 ) {
1497 rio_dprintk (RIO_DEBUG_INIT, "\nNo Hosts configured\n");
1498 return(0);
1499 }
1500
1501 for ( host=0; host < p->RIONumHosts; host++ ) {
1502 struct Host *HostP = &p->RIOHosts[host];
1503 switch ( HostP->Type ) {
1504 case RIO_AT:
1505 rio_dprintk (RIO_DEBUG_INIT, "AT BUS : found the card at 0x%x\n", HostP->PaddrP);
1506 }
1507 }
1508 return 0;
1509}
1510#endif
1511
1512static struct rioVersion stVersion;
1513
1514struct rioVersion *
1515RIOVersid(void)
1516{
1517 strlcpy(stVersion.version, "RIO driver for linux V1.0",
1518 sizeof(stVersion.version));
1519 strlcpy(stVersion.buildDate, __DATE__,
1520 sizeof(stVersion.buildDate));
1521
1522 return &stVersion;
1523}
1524
1525#if 0
1526int
1527RIOMapin(paddr, size, vaddr)
1528paddr_t paddr;
1529int size;
1530caddr_t * vaddr;
1531{
1532 *vaddr = (caddr_t)permap( (long)paddr, size);
1533 return ((int)*vaddr);
1534}
1535
1536void
1537RIOMapout(paddr, size, vaddr)
1538paddr_t paddr;
1539long size;
1540caddr_t vaddr;
1541{
1542}
1543#endif
1544
1545
1546void
1547RIOHostReset(Type, DpRamP, Slot)
1548uint Type;
1549volatile struct DpRam *DpRamP;
1550uint Slot;
1551{
1552 /*
1553 ** Reset the Tpu
1554 */
1555 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type);
1556 switch ( Type ) {
1557 case RIO_AT:
1558 rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n");
1559 WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
1560 INTERRUPT_DISABLE | BYTE_OPERATION |
1561 SLOW_LINKS | SLOW_AT_BUS);
1562 WBYTE(DpRamP->DpResetTpu, 0xFF);
1563 rio_udelay (3);
1564
1565 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n");
1566 WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
1567 INTERRUPT_DISABLE | BYTE_OPERATION |
1568 SLOW_LINKS | SLOW_AT_BUS);
1569 WBYTE(DpRamP->DpResetTpu, 0xFF);
1570 rio_udelay (3);
1571 break;
1572#ifdef FUTURE_RELEASE
1573 case RIO_EISA:
1574 /*
1575 ** Bet this doesn't work!
1576 */
1577 OUTBZ( Slot, EISA_CONTROL_PORT,
1578 EISA_TP_RUN | EISA_TP_BUS_DISABLE |
1579 EISA_TP_SLOW_LINKS | EISA_TP_BOOT_FROM_RAM );
1580 OUTBZ( Slot, EISA_CONTROL_PORT,
1581 EISA_TP_RESET | EISA_TP_BUS_DISABLE |
1582 EISA_TP_SLOW_LINKS | EISA_TP_BOOT_FROM_RAM );
1583 suspend( 3 );
1584 OUTBZ( Slot, EISA_CONTROL_PORT,
1585 EISA_TP_RUN | EISA_TP_BUS_DISABLE |
1586 EISA_TP_SLOW_LINKS | EISA_TP_BOOT_FROM_RAM );
1587 break;
1588 case RIO_MCA:
1589 WBYTE(DpRamP->DpControl , McaTpBootFromRam | McaTpBusDisable );
1590 WBYTE(DpRamP->DpResetTpu , 0xFF );
1591 suspend( 3 );
1592 WBYTE(DpRamP->DpControl , McaTpBootFromRam | McaTpBusDisable );
1593 WBYTE(DpRamP->DpResetTpu , 0xFF );
1594 suspend( 3 );
1595 break;
1596#endif
1597 case RIO_PCI:
1598 rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n");
1599 DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM;
1600 DpRamP->DpResetInt = 0xFF;
1601 DpRamP->DpResetTpu = 0xFF;
1602 rio_udelay (100);
1603 /* for (i=0; i<6000; i++); */
1604 /* suspend( 3 ); */
1605 break;
1606#ifdef FUTURE_RELEASE
1607 default:
1608 Rprintf(RIOMesgNoSupport,Type,DpRamP,Slot);
1609 return;
1610#endif
1611
1612 default:
1613 rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n");
1614 break;
1615 }
1616 return;
1617}
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
new file mode 100644
index 000000000000..e42e7b50bf6b
--- /dev/null
+++ b/drivers/char/rio/riointr.c
@@ -0,0 +1,951 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riointr.c
24** SID : 1.2
25** Last Modified : 11/6/98 10:33:44
26** Retrieved : 11/6/98 10:33:49
27**
28** ident @(#)riointr.c 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32#ifdef SCCS_LABELS
33static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2";
34#endif
35
36
37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <linux/tty.h>
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/string.h>
44#include <asm/semaphore.h>
45#include <asm/uaccess.h>
46
47#include <linux/termios.h>
48#include <linux/serial.h>
49
50#include <linux/generic_serial.h>
51
52#include <linux/delay.h>
53
54#include "linux_compat.h"
55#include "rio_linux.h"
56#include "typdef.h"
57#include "pkt.h"
58#include "daemon.h"
59#include "rio.h"
60#include "riospace.h"
61#include "top.h"
62#include "cmdpkt.h"
63#include "map.h"
64#include "riotypes.h"
65#include "rup.h"
66#include "port.h"
67#include "riodrvr.h"
68#include "rioinfo.h"
69#include "func.h"
70#include "errors.h"
71#include "pci.h"
72
73#include "parmmap.h"
74#include "unixrup.h"
75#include "board.h"
76#include "host.h"
77#include "error.h"
78#include "phb.h"
79#include "link.h"
80#include "cmdblk.h"
81#include "route.h"
82#include "control.h"
83#include "cirrus.h"
84#include "rioioctl.h"
85
86
87static void RIOReceive(struct rio_info *, struct Port *);
88
89
90static char *firstchars (char *p, int nch)
91{
92 static char buf[2][128];
93 static int t=0;
94 t = ! t;
95 memcpy (buf[t], p, nch);
96 buf[t][nch] = 0;
97 return buf[t];
98}
99
100
101#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask))
102/* Enable and start the transmission of packets */
103void
104RIOTxEnable(en)
105char * en;
106{
107 struct Port * PortP;
108 struct rio_info *p;
109 struct tty_struct* tty;
110 int c;
111 struct PKT * PacketP;
112 unsigned long flags;
113
114 PortP = (struct Port *)en;
115 p = (struct rio_info *)PortP->p;
116 tty = PortP->gs.tty;
117
118
119 rio_dprintk (RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n",
120 PortP->PortNum, PortP->gs.xmit_cnt);
121
122 if (!PortP->gs.xmit_cnt) return;
123
124
125 /* This routine is an order of magnitude simpler than the specialix
126 version. One of the disadvantages is that this version will send
127 an incomplete packet (usually 64 bytes instead of 72) once for
128 every 4k worth of data. Let's just say that this won't influence
129 performance significantly..... */
130
131 rio_spin_lock_irqsave(&PortP->portSem, flags);
132
133 while (can_add_transmit( &PacketP, PortP )) {
134 c = PortP->gs.xmit_cnt;
135 if (c > PKT_MAX_DATA_LEN) c = PKT_MAX_DATA_LEN;
136
137 /* Don't copy past the end of the source buffer */
138 if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail)
139 c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail;
140
141 { int t;
142 t = (c > 10)?10:c;
143
144 rio_dprintk (RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n",
145 PortP->PortNum, c,
146 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail , t),
147 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t));
148 }
149 /* If for one reason or another, we can't copy more data,
150 we're done! */
151 if (c == 0) break;
152
153 rio_memcpy_toio (PortP->HostP->Caddr, (caddr_t)PacketP->data,
154 PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
155 /* udelay (1); */
156
157 writeb (c, &(PacketP->len));
158 if (!( PortP->State & RIO_DELETED ) ) {
159 add_transmit ( PortP );
160 /*
161 ** Count chars tx'd for port statistics reporting
162 */
163 if ( PortP->statsGather )
164 PortP->txchars += c;
165 }
166 PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE-1);
167 PortP->gs.xmit_cnt -= c;
168 }
169
170 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
171
172 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2*PKT_MAX_DATA_LEN)) {
173 rio_dprintk (RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....",
174 (int)(PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)),
175 PortP->gs.wakeup_chars, PortP->gs.xmit_cnt);
176 if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
177 PortP->gs.tty->ldisc.write_wakeup)
178 (PortP->gs.tty->ldisc.write_wakeup)(PortP->gs.tty);
179 rio_dprintk (RIO_DEBUG_INTR, "(%d/%d)\n",
180 PortP->gs.wakeup_chars, PortP->gs.xmit_cnt);
181 wake_up_interruptible(&PortP->gs.tty->write_wait);
182 }
183
184}
185
186
187/*
188** RIO Host Service routine. Does all the work traditionally associated with an
189** interrupt.
190*/
191static int RupIntr;
192static int RxIntr;
193static int TxIntr;
194void
195RIOServiceHost(p, HostP, From)
196struct rio_info * p;
197struct Host *HostP;
198int From;
199{
200 rio_spin_lock (&HostP->HostLock);
201 if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
202 static int t =0;
203 rio_spin_unlock (&HostP->HostLock);
204 if ((t++ % 200) == 0)
205 rio_dprintk (RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int)HostP->Flags);
206 return;
207 }
208 rio_spin_unlock (&HostP->HostLock);
209
210 if ( RWORD( HostP->ParmMapP->rup_intr ) ) {
211 WWORD( HostP->ParmMapP->rup_intr , 0 );
212 p->RIORupCount++;
213 RupIntr++;
214 rio_dprintk (RIO_DEBUG_INTR, "rio: RUP interrupt on host %d\n", HostP-p->RIOHosts);
215 RIOPollHostCommands(p, HostP );
216 }
217
218 if ( RWORD( HostP->ParmMapP->rx_intr ) ) {
219 int port;
220
221 WWORD( HostP->ParmMapP->rx_intr , 0 );
222 p->RIORxCount++;
223 RxIntr++;
224
225 rio_dprintk (RIO_DEBUG_INTR, "rio: RX interrupt on host %d\n", HostP-p->RIOHosts);
226 /*
227 ** Loop through every port. If the port is mapped into
228 ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
229 ** worth checking. If the port isn't open, grab any packets
230 ** hanging on its receive queue and stuff them on the free
231 ** list; check for commands on the way.
232 */
233 for ( port=p->RIOFirstPortsBooted;
234 port<p->RIOLastPortsBooted+PORTS_PER_RTA; port++ ) {
235 struct Port *PortP = p->RIOPortp[port];
236 struct tty_struct *ttyP;
237 struct PKT *PacketP;
238
239 /*
240 ** not mapped in - most of the RIOPortp[] information
241 ** has not been set up!
242 ** Optimise: ports come in bundles of eight.
243 */
244 if ( !PortP->Mapped ) {
245 port += 7;
246 continue; /* with the next port */
247 }
248
249 /*
250 ** If the host board isn't THIS host board, check the next one.
251 ** optimise: ports come in bundles of eight.
252 */
253 if ( PortP->HostP != HostP ) {
254 port += 7;
255 continue;
256 }
257
258 /*
259 ** Let us see - is the port open? If not, then don't service it.
260 */
261 if ( !( PortP->PortState & PORT_ISOPEN ) ) {
262 continue;
263 }
264
265 /*
266 ** find corresponding tty structure. The process of mapping
267 ** the ports puts these here.
268 */
269 ttyP = PortP->gs.tty;
270
271 /*
272 ** Lock the port before we begin working on it.
273 */
274 rio_spin_lock(&PortP->portSem);
275
276 /*
277 ** Process received data if there is any.
278 */
279 if ( can_remove_receive( &PacketP, PortP ) )
280 RIOReceive(p, PortP);
281
282 /*
283 ** If there is no data left to be read from the port, and
284 ** it's handshake bit is set, then we must clear the handshake,
285 ** so that that downstream RTA is re-enabled.
286 */
287 if ( !can_remove_receive( &PacketP, PortP ) &&
288 ( RWORD( PortP->PhbP->handshake )==PHB_HANDSHAKE_SET ) ) {
289 /*
290 ** MAGIC! ( Basically, handshake the RX buffer, so that
291 ** the RTAs upstream can be re-enabled. )
292 */
293 rio_dprintk (RIO_DEBUG_INTR, "Set RX handshake bit\n");
294 WWORD( PortP->PhbP->handshake,
295 PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET );
296 }
297 rio_spin_unlock(&PortP->portSem);
298 }
299 }
300
301 if ( RWORD( HostP->ParmMapP->tx_intr ) ) {
302 int port;
303
304 WWORD( HostP->ParmMapP->tx_intr , 0);
305
306 p->RIOTxCount++;
307 TxIntr++;
308 rio_dprintk (RIO_DEBUG_INTR, "rio: TX interrupt on host %d\n", HostP-p->RIOHosts);
309
310 /*
311 ** Loop through every port.
312 ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX
313 ** associated ) then it is worth checking.
314 */
315 for ( port=p->RIOFirstPortsBooted;
316 port<p->RIOLastPortsBooted+PORTS_PER_RTA; port++ ) {
317 struct Port *PortP = p->RIOPortp[port];
318 struct tty_struct *ttyP;
319 struct PKT *PacketP;
320
321 /*
322 ** not mapped in - most of the RIOPortp[] information
323 ** has not been set up!
324 */
325 if ( !PortP->Mapped ) {
326 port += 7;
327 continue; /* with the next port */
328 }
329
330 /*
331 ** If the host board isn't running, then its data structures
332 ** are no use to us - continue quietly.
333 */
334 if ( PortP->HostP != HostP ) {
335 port += 7;
336 continue; /* with the next port */
337 }
338
339 /*
340 ** Let us see - is the port open? If not, then don't service it.
341 */
342 if ( !( PortP->PortState & PORT_ISOPEN ) ) {
343 continue;
344 }
345
346 rio_dprintk (RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
347 /*
348 ** Lock the port before we begin working on it.
349 */
350 rio_spin_lock(&PortP->portSem);
351
352 /*
353 ** If we can't add anything to the transmit queue, then
354 ** we need do none of this processing.
355 */
356 if ( !can_add_transmit( &PacketP, PortP ) ) {
357 rio_dprintk (RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
358 rio_spin_unlock(&PortP->portSem);
359 continue;
360 }
361
362 /*
363 ** find corresponding tty structure. The process of mapping
364 ** the ports puts these here.
365 */
366 ttyP = PortP->gs.tty;
367 /* If ttyP is NULL, the port is getting closed. Forget about it. */
368 if (!ttyP) {
369 rio_dprintk (RIO_DEBUG_INTR, "no tty, so skipping.\n");
370 rio_spin_unlock(&PortP->portSem);
371 continue;
372 }
373 /*
374 ** If there is more room available we start up the transmit
375 ** data process again. This can be direct I/O, if the cookmode
376 ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the
377 ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch
378 ** characters via the line discipline. We must always call
379 ** the line discipline,
380 ** so that user input characters can be echoed correctly.
381 **
382 ** ++++ Update +++++
383 ** With the advent of double buffering, we now see if
384 ** TxBufferOut-In is non-zero. If so, then we copy a packet
385 ** to the output place, and set it going. If this empties
386 ** the buffer, then we must issue a wakeup( ) on OUT.
387 ** If it frees space in the buffer then we must issue
388 ** a wakeup( ) on IN.
389 **
390 ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we
391 ** have to send a WFLUSH command down the PHB, to mark the
392 ** end point of a WFLUSH. We also need to clear out any
393 ** data from the double buffer! ( note that WflushFlag is a
394 ** *count* of the number of WFLUSH commands outstanding! )
395 **
396 ** ++++ And there's more!
397 ** If an RTA is powered off, then on again, and rebooted,
398 ** whilst it has ports open, then we need to re-open the ports.
399 ** ( reasonable enough ). We can't do this when we spot the
400 ** re-boot, in interrupt time, because the queue is probably
401 ** full. So, when we come in here, we need to test if any
402 ** ports are in this condition, and re-open the port before
403 ** we try to send any more data to it. Now, the re-booted
404 ** RTA will be discarding packets from the PHB until it
405 ** receives this open packet, but don't worry tooo much
406 ** about that. The one thing that is interesting is the
407 ** combination of this effect and the WFLUSH effect!
408 */
409 /* For now don't handle RTA reboots. -- REW.
410 Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */
411 if ( PortP->MagicFlags ) {
412#if 1
413 if ( PortP->MagicFlags & MAGIC_REBOOT ) {
414 /*
415 ** well, the RTA has been rebooted, and there is room
416 ** on its queue to add the open packet that is required.
417 **
418 ** The messy part of this line is trying to decide if
419 ** we need to call the Param function as a tty or as
420 ** a modem.
421 ** DONT USE CLOCAL AS A TEST FOR THIS!
422 **
423 ** If we can't param the port, then move on to the
424 ** next port.
425 */
426 PortP->InUse = NOT_INUSE;
427
428 rio_spin_unlock(&PortP->portSem);
429 if ( RIOParam(PortP, OPEN, ((PortP->Cor2Copy &
430 (COR2_RTSFLOW|COR2_CTSFLOW ) )==
431 (COR2_RTSFLOW|COR2_CTSFLOW ) ) ?
432 TRUE : FALSE, DONT_SLEEP ) == RIO_FAIL ) {
433 continue; /* with next port */
434 }
435 rio_spin_lock(&PortP->portSem);
436 PortP->MagicFlags &= ~MAGIC_REBOOT;
437 }
438#endif
439
440 /*
441 ** As mentioned above, this is a tacky hack to cope
442 ** with WFLUSH
443 */
444 if ( PortP->WflushFlag ) {
445 rio_dprintk (RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
446
447 if ( PortP->InUse )
448 rio_dprintk (RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
449 }
450
451 while ( PortP->WflushFlag &&
452 can_add_transmit( &PacketP, PortP ) &&
453 ( PortP->InUse == NOT_INUSE ) ) {
454 int p;
455 struct PktCmd *PktCmdP;
456
457 rio_dprintk (RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
458 /*
459 ** make it look just like a WFLUSH command
460 */
461 PktCmdP = ( struct PktCmd * )&PacketP->data[0];
462
463 WBYTE( PktCmdP->Command , WFLUSH );
464
465 p = PortP->HostPort % ( ushort )PORTS_PER_RTA;
466
467 /*
468 ** If second block of ports for 16 port RTA, add 8
469 ** to index 8-15.
470 */
471 if ( PortP->SecondBlock )
472 p += PORTS_PER_RTA;
473
474 WBYTE( PktCmdP->PhbNum, p );
475
476 /*
477 ** to make debuggery easier
478 */
479 WBYTE( PacketP->data[ 2], 'W' );
480 WBYTE( PacketP->data[ 3], 'F' );
481 WBYTE( PacketP->data[ 4], 'L' );
482 WBYTE( PacketP->data[ 5], 'U' );
483 WBYTE( PacketP->data[ 6], 'S' );
484 WBYTE( PacketP->data[ 7], 'H' );
485 WBYTE( PacketP->data[ 8], ' ' );
486 WBYTE( PacketP->data[ 9], '0'+PortP->WflushFlag );
487 WBYTE( PacketP->data[10], ' ' );
488 WBYTE( PacketP->data[11], ' ' );
489 WBYTE( PacketP->data[12], '\0' );
490
491 /*
492 ** its two bytes long!
493 */
494 WBYTE( PacketP->len , PKT_CMD_BIT | 2 );
495
496 /*
497 ** queue it!
498 */
499 if ( !( PortP->State & RIO_DELETED ) ) {
500 add_transmit( PortP );
501 /*
502 ** Count chars tx'd for port statistics reporting
503 */
504 if ( PortP->statsGather )
505 PortP->txchars += 2;
506 }
507
508 if ( --( PortP->WflushFlag ) == 0 ) {
509 PortP->MagicFlags &= ~MAGIC_FLUSH;
510 }
511
512 rio_dprintk (RIO_DEBUG_INTR, "Wflush count now stands at %d\n",
513 PortP->WflushFlag);
514 }
515 if ( PortP->MagicFlags & MORE_OUTPUT_EYGOR ) {
516 if ( PortP->MagicFlags & MAGIC_FLUSH ) {
517 PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
518 }
519 else {
520 if ( !can_add_transmit( &PacketP, PortP ) ) {
521 rio_spin_unlock(&PortP->portSem);
522 continue;
523 }
524 rio_spin_unlock(&PortP->portSem);
525 RIOTxEnable((char *)PortP);
526 rio_spin_lock(&PortP->portSem);
527 PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
528 }
529 }
530 }
531
532
533 /*
534 ** If we can't add anything to the transmit queue, then
535 ** we need do none of the remaining processing.
536 */
537 if (!can_add_transmit( &PacketP, PortP ) ) {
538 rio_spin_unlock(&PortP->portSem);
539 continue;
540 }
541
542 rio_spin_unlock(&PortP->portSem);
543 RIOTxEnable((char *)PortP);
544 }
545 }
546}
547
548/*
549** Routine for handling received data for clist drivers.
550** NB: Called with the tty locked. The spl from the lockb( ) is passed.
551** we return the ttySpl level that we re-locked at.
552*/
553static void
554RIOReceive(p, PortP)
555struct rio_info * p;
556struct Port * PortP;
557{
558 struct tty_struct *TtyP;
559 register ushort transCount;
560 struct PKT *PacketP;
561 register uint DataCnt;
562 uchar * ptr;
563 int copied =0;
564
565 static int intCount, RxIntCnt;
566
567 /*
568 ** The receive data process is to remove packets from the
569 ** PHB until there aren't any more or the current cblock
570 ** is full. When this occurs, there will be some left over
571 ** data in the packet, that we must do something with.
572 ** As we haven't unhooked the packet from the read list
573 ** yet, we can just leave the packet there, having first
574 ** made a note of how far we got. This means that we need
575 ** a pointer per port saying where we start taking the
576 ** data from - this will normally be zero, but when we
577 ** run out of space it will be set to the offset of the
578 ** next byte to copy from the packet data area. The packet
579 ** length field is decremented by the number of bytes that
580 ** we succesfully removed from the packet. When this reaches
581 ** zero, we reset the offset pointer to be zero, and free
582 ** the packet from the front of the queue.
583 */
584
585 intCount++;
586
587 TtyP = PortP->gs.tty;
588 if (!TtyP) {
589 rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
590 return;
591 }
592
593 if (PortP->State & RIO_THROTTLE_RX) {
594 rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
595 return;
596 }
597
598 if ( PortP->State & RIO_DELETED )
599 {
600 while ( can_remove_receive( &PacketP, PortP ) )
601 {
602 remove_receive( PortP );
603 put_free_end( PortP->HostP, PacketP );
604 }
605 }
606 else
607 {
608 /*
609 ** loop, just so long as:
610 ** i ) there's some data ( i.e. can_remove_receive )
611 ** ii ) we haven't been blocked
612 ** iii ) there's somewhere to put the data
613 ** iv ) we haven't outstayed our welcome
614 */
615 transCount = 1;
616 while ( can_remove_receive(&PacketP, PortP)
617 && transCount)
618 {
619#ifdef STATS
620 PortP->Stat.RxIntCnt++;
621#endif /* STATS */
622 RxIntCnt++;
623
624 /*
625 ** check that it is not a command!
626 */
627 if ( PacketP->len & PKT_CMD_BIT ) {
628 rio_dprintk (RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
629 /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
630 rio_dprintk (RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit);
631 rio_dprintk (RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port);
632 rio_dprintk (RIO_DEBUG_INTR, " src_unit = %d\n", PacketP->src_unit);
633 rio_dprintk (RIO_DEBUG_INTR, " src_port = %d\n", PacketP->src_port);
634 rio_dprintk (RIO_DEBUG_INTR, " len = %d\n", PacketP->len);
635 rio_dprintk (RIO_DEBUG_INTR, " control = %d\n", PacketP->control);
636 rio_dprintk (RIO_DEBUG_INTR, " csum = %d\n", PacketP->csum);
637 rio_dprintk (RIO_DEBUG_INTR, " data bytes: ");
638 for ( DataCnt=0; DataCnt<PKT_MAX_DATA_LEN; DataCnt++ )
639 rio_dprintk (RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]);
640 remove_receive( PortP );
641 put_free_end( PortP->HostP, PacketP );
642 continue; /* with next packet */
643 }
644
645 /*
646 ** How many characters can we move 'upstream' ?
647 **
648 ** Determine the minimum of the amount of data
649 ** available and the amount of space in which to
650 ** put it.
651 **
652 ** 1. Get the packet length by masking 'len'
653 ** for only the length bits.
654 ** 2. Available space is [buffer size] - [space used]
655 **
656 ** Transfer count is the minimum of packet length
657 ** and available space.
658 */
659
660 transCount = min_t(unsigned int, PacketP->len & PKT_LEN_MASK,
661 TTY_FLIPBUF_SIZE - TtyP->flip.count);
662 rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n",
663 PortP->PortNum, transCount);
664 /*
665 ** To use the following 'kkprintfs' for debugging - change the '#undef'
666 ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
667 ** driver).
668 */
669#undef ___DEBUG_IT___
670#ifdef ___DEBUG_IT___
671 kkprintf("I:%d R:%d P:%d Q:%d C:%d F:%x ",
672 intCount,
673 RxIntCnt,
674 PortP->PortNum,
675 TtyP->rxqueue.count,
676 transCount,
677 TtyP->flags );
678#endif
679 ptr = (uchar *) PacketP->data + PortP->RxDataStart;
680
681 rio_memcpy_fromio (TtyP->flip.char_buf_ptr, ptr, transCount);
682 memset(TtyP->flip.flag_buf_ptr, TTY_NORMAL, transCount);
683
684#ifdef STATS
685 /*
686 ** keep a count for statistical purposes
687 */
688 PortP->Stat.RxCharCnt += transCount;
689#endif
690 PortP->RxDataStart += transCount;
691 PacketP->len -= transCount;
692 copied += transCount;
693 TtyP->flip.count += transCount;
694 TtyP->flip.char_buf_ptr += transCount;
695 TtyP->flip.flag_buf_ptr += transCount;
696
697
698#ifdef ___DEBUG_IT___
699 kkprintf("T:%d L:%d\n", DataCnt, PacketP->len );
700#endif
701
702 if ( PacketP->len == 0 )
703 {
704 /*
705 ** If we have emptied the packet, then we can
706 ** free it, and reset the start pointer for
707 ** the next packet.
708 */
709 remove_receive( PortP );
710 put_free_end( PortP->HostP, PacketP );
711 PortP->RxDataStart = 0;
712#ifdef STATS
713 /*
714 ** more lies ( oops, I mean statistics )
715 */
716 PortP->Stat.RxPktCnt++;
717#endif /* STATS */
718 }
719 }
720 }
721 if (copied) {
722 rio_dprintk (RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
723 tty_flip_buffer_push (TtyP);
724 }
725
726 return;
727}
728
729#ifdef FUTURE_RELEASE
730/*
731** The proc routine called by the line discipline to do the work for it.
732** The proc routine works hand in hand with the interrupt routine.
733*/
734int
735riotproc(p, tp, cmd, port)
736struct rio_info * p;
737register struct ttystatics *tp;
738int cmd;
739int port;
740{
741 register struct Port *PortP;
742 int SysPort;
743 struct PKT *PacketP;
744
745 SysPort = port; /* Believe me, it works. */
746
747 if ( SysPort < 0 || SysPort >= RIO_PORTS ) {
748 rio_dprintk (RIO_DEBUG_INTR, "Illegal port %d derived from TTY in riotproc()\n",SysPort);
749 return 0;
750 }
751 PortP = p->RIOPortp[SysPort];
752
753 if ((uint)PortP->PhbP < (uint)PortP->Caddr ||
754 (uint)PortP->PhbP >= (uint)PortP->Caddr+SIXTY_FOUR_K ) {
755 rio_dprintk (RIO_DEBUG_INTR, "RIO: NULL or BAD PhbP on sys port %d in proc routine\n",
756 SysPort);
757 rio_dprintk (RIO_DEBUG_INTR, " PortP = 0x%x\n",PortP);
758 rio_dprintk (RIO_DEBUG_INTR, " PortP->PhbP = 0x%x\n",PortP->PhbP);
759 rio_dprintk (RIO_DEBUG_INTR, " PortP->Caddr = 0x%x\n",PortP->PhbP);
760 rio_dprintk (RIO_DEBUG_INTR, " PortP->HostPort = 0x%x\n",PortP->HostPort);
761 return 0;
762 }
763
764 switch(cmd) {
765 case T_WFLUSH:
766 rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH\n");
767 /*
768 ** Because of the spooky way the RIO works, we don't need
769 ** to issue a flush command on any of the SET*F commands,
770 ** as that causes trouble with getty and login, which issue
771 ** these commands to incur a READ flush, and rely on the fact
772 ** that the line discipline does a wait for drain for them.
773 ** As the rio doesn't wait for drain, the write flush would
774 ** destroy the Password: prompt. This isn't very friendly, so
775 ** here we only issue a WFLUSH command if we are in the interrupt
776 ** routine, or we aren't executing a SET*F command.
777 */
778 if ( PortP->HostP->InIntr || !PortP->FlushCmdBodge ) {
779 /*
780 ** form a wflush packet - 1 byte long, no data
781 */
782 if ( PortP->State & RIO_DELETED ) {
783 rio_dprintk (RIO_DEBUG_INTR, "WFLUSH on deleted RTA\n");
784 }
785 else {
786 if ( RIOPreemptiveCmd(p, PortP, WFLUSH ) == RIO_FAIL ) {
787 rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command failed\n");
788 }
789 else
790 rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command\n");
791 }
792 /*
793 ** WFLUSH operation - flush the data!
794 */
795 PortP->TxBufferIn = PortP->TxBufferOut = 0;
796 }
797 else {
798 rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command ignored\n");
799 }
800 /*
801 ** sort out the line discipline
802 */
803 if (PortP->CookMode == COOK_WELL)
804 goto start;
805 break;
806
807 case T_RESUME:
808 rio_dprintk (RIO_DEBUG_INTR, "T_RESUME\n");
809 /*
810 ** send pre-emptive resume packet
811 */
812 if ( PortP->State & RIO_DELETED ) {
813 rio_dprintk (RIO_DEBUG_INTR, "RESUME on deleted RTA\n");
814 }
815 else {
816 if ( RIOPreemptiveCmd(p, PortP, RESUME ) == RIO_FAIL ) {
817 rio_dprintk (RIO_DEBUG_INTR, "T_RESUME Command failed\n");
818 }
819 }
820 /*
821 ** and re-start the sender software!
822 */
823 if (PortP->CookMode == COOK_WELL)
824 goto start;
825 break;
826
827 case T_TIME:
828 rio_dprintk (RIO_DEBUG_INTR, "T_TIME\n");
829 /*
830 ** T_TIME is called when xDLY is set in oflags and
831 ** the line discipline timeout has expired. It's
832 ** function in life is to clear the TIMEOUT flag
833 ** and to re-start output to the port.
834 */
835 /*
836 ** Fall through and re-start output
837 */
838 case T_OUTPUT:
839start:
840 if ( PortP->MagicFlags & MAGIC_FLUSH ) {
841 PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
842 return 0;
843 }
844 RIOTxEnable((char *)PortP);
845 PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
846 /*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"T_OUTPUT finished\n");*/
847 break;
848
849 case T_SUSPEND:
850 rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND\n");
851 /*
852 ** send a suspend pre-emptive packet.
853 */
854 if ( PortP->State & RIO_DELETED ) {
855 rio_dprintk (RIO_DEBUG_INTR, "SUSPEND deleted RTA\n");
856 }
857 else {
858 if ( RIOPreemptiveCmd(p, PortP, SUSPEND ) == RIO_FAIL ) {
859 rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND Command failed\n");
860 }
861 }
862 /*
863 ** done!
864 */
865 break;
866
867 case T_BLOCK:
868 rio_dprintk (RIO_DEBUG_INTR, "T_BLOCK\n");
869 break;
870
871 case T_RFLUSH:
872 rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH\n");
873 if ( PortP->State & RIO_DELETED ) {
874 rio_dprintk (RIO_DEBUG_INTR, "RFLUSH on deleted RTA\n");
875 PortP->RxDataStart = 0;
876 }
877 else {
878 if ( RIOPreemptiveCmd( p, PortP, RFLUSH ) == RIO_FAIL ) {
879 rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH Command failed\n");
880 return 0;
881 }
882 PortP->RxDataStart = 0;
883 while ( can_remove_receive(&PacketP, PortP) ) {
884 remove_receive(PortP);
885 ShowPacket(DBG_PROC, PacketP );
886 put_free_end(PortP->HostP, PacketP );
887 }
888 if ( PortP->PhbP->handshake == PHB_HANDSHAKE_SET ) {
889 /*
890 ** MAGIC!
891 */
892 rio_dprintk (RIO_DEBUG_INTR, "Set receive handshake bit\n");
893 PortP->PhbP->handshake |= PHB_HANDSHAKE_RESET;
894 }
895 }
896 break;
897 /* FALLTHROUGH */
898 case T_UNBLOCK:
899 rio_dprintk (RIO_DEBUG_INTR, "T_UNBLOCK\n");
900 /*
901 ** If there is any data to receive set a timeout to service it.
902 */
903 RIOReceive(p, PortP);
904 break;
905
906 case T_BREAK:
907 rio_dprintk (RIO_DEBUG_INTR, "T_BREAK\n");
908 /*
909 ** Send a break command. For Sys V
910 ** this is a timed break, so we
911 ** send a SBREAK[time] packet
912 */
913 /*
914 ** Build a BREAK command
915 */
916 if ( PortP->State & RIO_DELETED ) {
917 rio_dprintk (RIO_DEBUG_INTR, "BREAK on deleted RTA\n");
918 }
919 else {
920 if (RIOShortCommand(PortP,SBREAK,2,
921 p->RIOConf.BreakInterval)==RIO_FAIL) {
922 rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
923 }
924 }
925
926 /*
927 ** done!
928 */
929 break;
930
931 case T_INPUT:
932 rio_dprintk (RIO_DEBUG_INTR, "Proc T_INPUT called - I don't know what to do!\n");
933 break;
934 case T_PARM:
935 rio_dprintk (RIO_DEBUG_INTR, "Proc T_PARM called - I don't know what to do!\n");
936 break;
937
938 case T_SWTCH:
939 rio_dprintk (RIO_DEBUG_INTR, "Proc T_SWTCH called - I don't know what to do!\n");
940 break;
941
942 default:
943 rio_dprintk (RIO_DEBUG_INTR, "Proc UNKNOWN command %d\n",cmd);
944 }
945 /*
946 ** T_OUTPUT returns without passing through this point!
947 */
948 /*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"riotproc done\n");*/
949 return(0);
950}
951#endif
diff --git a/drivers/char/rio/rioioctl.h b/drivers/char/rio/rioioctl.h
new file mode 100644
index 000000000000..c3d679733c9a
--- /dev/null
+++ b/drivers/char/rio/rioioctl.h
@@ -0,0 +1,103 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rioioctl.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:13
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)rioioctl.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rioioctl_h__
34#define __rioioctl_h__
35
36#ifdef SCCS_LABELS
37static char *_rioioctl_h_sccs_ = "@(#)rioioctl.h 1.2";
38#endif
39
40/*
41** RIO device driver - user ioctls and associated structures.
42*/
43
44struct portStats {
45 int port;
46 int gather;
47 ulong txchars;
48 ulong rxchars;
49 ulong opens;
50 ulong closes;
51 ulong ioctls;
52};
53
54
55#define rIOC ('r'<<8)
56#define TCRIOSTATE (rIOC | 1)
57#define TCRIOXPON (rIOC | 2)
58#define TCRIOXPOFF (rIOC | 3)
59#define TCRIOXPCPS (rIOC | 4)
60#define TCRIOXPRINT (rIOC | 5)
61#define TCRIOIXANYON (rIOC | 6)
62#define TCRIOIXANYOFF (rIOC | 7)
63#define TCRIOIXONON (rIOC | 8)
64#define TCRIOIXONOFF (rIOC | 9)
65#define TCRIOMBIS (rIOC | 10)
66#define TCRIOMBIC (rIOC | 11)
67#define TCRIOTRIAD (rIOC | 12)
68#define TCRIOTSTATE (rIOC | 13)
69
70/*
71** 15.10.1998 ARG - ESIL 0761 part fix
72** Add RIO ioctls for manipulating RTS and CTS flow control, (as LynxOS
73** appears to not support hardware flow control).
74*/
75#define TCRIOCTSFLOWEN (rIOC | 14) /* enable CTS flow control */
76#define TCRIOCTSFLOWDIS (rIOC | 15) /* disable CTS flow control */
77#define TCRIORTSFLOWEN (rIOC | 16) /* enable RTS flow control */
78#define TCRIORTSFLOWDIS (rIOC | 17) /* disable RTS flow control */
79
80/*
81** 09.12.1998 ARG - ESIL 0776 part fix
82** Definition for 'RIOC' also appears in daemon.h, so we'd better do a
83** #ifndef here first.
84** 'RIO_QUICK_CHECK' also #define'd here as this ioctl is now
85** allowed to be used by customers.
86**
87** 05.02.1999 ARG -
88** This is what I've decied to do with ioctls etc., which are intended to be
89** invoked from users applications :
90** Anything that needs to be defined here will be removed from daemon.h, that
91** way it won't end up having to be defined/maintained in two places. The only
92** consequence of this is that this file should now be #include'd by daemon.h
93**
94** 'stats' ioctls now #define'd here as they are to be used by customers.
95*/
96#define RIOC ('R'<<8)|('i'<<16)|('o'<<24)
97
98#define RIO_QUICK_CHECK (RIOC | 105)
99#define RIO_GATHER_PORT_STATS (RIOC | 193)
100#define RIO_RESET_PORT_STATS (RIOC | 194)
101#define RIO_GET_PORT_STATS (RIOC | 195)
102
103#endif /* __rioioctl_h__ */
diff --git a/drivers/char/rio/riolocks.h b/drivers/char/rio/riolocks.h
new file mode 100644
index 000000000000..0e0cdacebe0b
--- /dev/null
+++ b/drivers/char/rio/riolocks.h
@@ -0,0 +1,43 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riolocks.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:13
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)riolocks.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_riolocks_h__
34#define __rio_riolocks_h__
35
36#ifdef SCCS_LABELS
37static char *_riolocks_h_sccs_ = "@(#)riolocks.h 1.2";
38#endif
39
40#define LOCKB(lk) lockb(lk);
41#define UNLOCKB(lk, oldspl) unlockb(lk, oldspl);
42
43#endif
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
new file mode 100644
index 000000000000..f10916326ecc
--- /dev/null
+++ b/drivers/char/rio/rioparam.c
@@ -0,0 +1,744 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rioparam.c
24** SID : 1.3
25** Last Modified : 11/6/98 10:33:45
26** Retrieved : 11/6/98 10:33:50
27**
28** ident @(#)rioparam.c 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifdef SCCS_LABELS
34static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3";
35#endif
36
37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <linux/tty.h>
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/string.h>
44#include <asm/semaphore.h>
45#include <asm/uaccess.h>
46
47#include <linux/termios.h>
48#include <linux/serial.h>
49
50#include <linux/generic_serial.h>
51
52
53#include "linux_compat.h"
54#include "rio_linux.h"
55#include "typdef.h"
56#include "pkt.h"
57#include "daemon.h"
58#include "rio.h"
59#include "riospace.h"
60#include "top.h"
61#include "cmdpkt.h"
62#include "map.h"
63#include "riotypes.h"
64#include "rup.h"
65#include "port.h"
66#include "riodrvr.h"
67#include "rioinfo.h"
68#include "func.h"
69#include "errors.h"
70#include "pci.h"
71
72#include "parmmap.h"
73#include "unixrup.h"
74#include "board.h"
75#include "host.h"
76#include "error.h"
77#include "phb.h"
78#include "link.h"
79#include "cmdblk.h"
80#include "route.h"
81#include "control.h"
82#include "cirrus.h"
83#include "rioioctl.h"
84#include "param.h"
85#include "list.h"
86#include "sam.h"
87
88
89
90/*
91** The Scam, based on email from jeremyr@bugs.specialix.co.uk....
92**
93** To send a command on a particular port, you put a packet with the
94** command bit set onto the port. The command bit is in the len field,
95** and gets ORed in with the actual byte count.
96**
97** When you send a packet with the command bit set, then the first
98** data byte ( data[0] ) is interpretted as the command to execute.
99** It also governs what data structure overlay should accompany the packet.
100** Commands are defined in cirrus/cirrus.h
101**
102** If you want the command to pre-emt data already on the queue for the
103** port, set the pre-emptive bit in conjunction with the command bit.
104** It is not defined what will happen if you set the preemptive bit
105** on a packet that is NOT a command.
106**
107** Pre-emptive commands should be queued at the head of the queue using
108** add_start(), whereas normal commands and data are enqueued using
109** add_end().
110**
111** Most commands do not use the remaining bytes in the data array. The
112** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and
113** OPEN are currently analagous). With these three commands the following
114** 11 data bytes are all used to pass config information such as baud rate etc.
115** The fields are also defined in cirrus.h. Some contain straightforward
116** information such as the transmit XON character. Two contain the transmit and
117** receive baud rates respectively. For most baud rates there is a direct
118** mapping between the rates defined in <sys/termio.h> and the byte in the
119** packet. There are additional (non UNIX-standard) rates defined in
120** /u/dos/rio/cirrus/h/brates.h.
121**
122** The rest of the data fields contain approximations to the Cirrus registers
123** that are used to program number of bits etc. Each registers bit fields is
124** defined in cirrus.h.
125**
126** NB. Only use those bits that are defined as being driver specific
127** or common to the RTA and the driver.
128**
129** All commands going from RTA->Host will be dealt with by the Host code - you
130** will never see them. As with the SI there will be three fields to look out
131** for in each phb (not yet defined - needs defining a.s.a.p).
132**
133** modem_status - current state of handshake pins.
134**
135** port_status - current port status - equivalent to hi_stat for SI, indicates
136** if port is IDLE_OPEN, IDLE_CLOSED etc.
137**
138** break_status - bit X set if break has been received.
139**
140** Happy hacking.
141**
142*/
143
144/*
145** RIOParam is used to open or configure a port. You pass it a PortP,
146** which will have a tty struct attached to it. You also pass a command,
147** either OPEN or CONFIG. The port's setup is taken from the t_ fields
148** of the tty struct inside the PortP, and the port is either opened
149** or re-configured. You must also tell RIOParam if the device is a modem
150** device or not (i.e. top bit of minor number set or clear - take special
151** care when deciding on this!).
152** RIOParam neither flushes nor waits for drain, and is NOT preemptive.
153**
154** RIOParam assumes it will be called at splrio(), and also assumes
155** that CookMode is set correctly in the port structure.
156**
157** NB. for MPX
158** tty lock must NOT have been previously acquired.
159*/
160int
161RIOParam(PortP, cmd, Modem, SleepFlag)
162struct Port *PortP;
163int cmd;
164int Modem;
165int SleepFlag;
166{
167 register struct tty_struct *TtyP;
168 int retval;
169 register struct phb_param *phb_param_ptr;
170 PKT *PacketP;
171 int res;
172 uchar Cor1=0, Cor2=0, Cor4=0, Cor5=0;
173 uchar TxXon=0, TxXoff=0, RxXon=0, RxXoff=0;
174 uchar LNext=0, TxBaud=0, RxBaud=0;
175 int retries = 0xff;
176 unsigned long flags;
177
178 func_enter ();
179
180 TtyP = PortP->gs.tty;
181
182 rio_dprintk (RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",
183 PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);
184
185 if (!TtyP) {
186 rio_dprintk (RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n");
187
188 func_exit ();
189
190 return RIO_FAIL;
191 }
192 rio_spin_lock_irqsave(&PortP->portSem, flags );
193
194 if (cmd == OPEN) {
195 /*
196 ** If the port is set to store or lock the parameters, and it is
197 ** paramed with OPEN, we want to restore the saved port termio, but
198 ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot.
199 */
200#if 0
201 if (PortP->FirstOpen) {
202 PortP->StoredTty.iflag = TtyP->tm.c_iflag;
203 PortP->StoredTty.oflag = TtyP->tm.c_oflag;
204 PortP->StoredTty.cflag = TtyP->tm.c_cflag;
205 PortP->StoredTty.lflag = TtyP->tm.c_lflag;
206 PortP->StoredTty.line = TtyP->tm.c_line;
207 for (i = 0; i < NCC + 5; i++)
208 PortP->StoredTty.cc[i] = TtyP->tm.c_cc[i];
209 PortP->FirstOpen = 0;
210 }
211 else if (PortP->Store || PortP->Lock) {
212 rio_dprintk (RIO_DEBUG_PARAM, "OPEN: Restoring stored/locked params\n");
213 TtyP->tm.c_iflag = PortP->StoredTty.iflag;
214 TtyP->tm.c_oflag = PortP->StoredTty.oflag;
215 TtyP->tm.c_cflag = PortP->StoredTty.cflag;
216 TtyP->tm.c_lflag = PortP->StoredTty.lflag;
217 TtyP->tm.c_line = PortP->StoredTty.line;
218 for (i = 0; i < NCC + 5; i++)
219 TtyP->tm.c_cc[i] = PortP->StoredTty.cc[i];
220 }
221#endif
222 }
223
224 /*
225 ** wait for space
226 */
227 while ( !(res=can_add_transmit(&PacketP,PortP)) ||
228 (PortP->InUse != NOT_INUSE) ) {
229 if (retries -- <= 0) {
230 break;
231 }
232 if ( PortP->InUse != NOT_INUSE ) {
233 rio_dprintk (RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n");
234 }
235
236 if ( !res ) {
237 rio_dprintk (RIO_DEBUG_PARAM, "Port has no space on transmit queue\n");
238 }
239
240 if ( SleepFlag != OK_TO_SLEEP ) {
241 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
242 func_exit();
243
244 return RIO_FAIL;
245 }
246
247 rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit\n");
248 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
249 retval = RIODelay(PortP, HUNDRED_MS);
250 rio_spin_lock_irqsave( &PortP->portSem, flags);
251 if (retval == RIO_FAIL) {
252 rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n");
253 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
254 pseterr(EINTR);
255 func_exit();
256
257 return RIO_FAIL;
258 }
259 if ( PortP->State & RIO_DELETED ) {
260 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
261 func_exit ();
262
263 return RIO_SUCCESS;
264 }
265 }
266
267 if (!res) {
268 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
269 func_exit ();
270
271 return RIO_FAIL;
272 }
273
274 rio_dprintk (RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n",res);
275 rio_dprintk (RIO_DEBUG_PARAM, "Packet is 0x%x\n",(int) PacketP);
276
277 phb_param_ptr = (struct phb_param *)PacketP->data;
278
279
280#if 0
281 /*
282 ** COR 1
283 */
284 if ( TtyP->tm.c_iflag & INPCK ) {
285 rio_dprintk (RIO_DEBUG_PARAM, "Parity checking on input enabled\n");
286 Cor1 |= COR1_INPCK;
287 }
288#endif
289
290 switch ( TtyP->termios->c_cflag & CSIZE ) {
291 case CS5:
292 {
293 rio_dprintk (RIO_DEBUG_PARAM, "5 bit data\n");
294 Cor1 |= COR1_5BITS;
295 break;
296 }
297 case CS6:
298 {
299 rio_dprintk (RIO_DEBUG_PARAM, "6 bit data\n");
300 Cor1 |= COR1_6BITS;
301 break;
302 }
303 case CS7:
304 {
305 rio_dprintk (RIO_DEBUG_PARAM, "7 bit data\n");
306 Cor1 |= COR1_7BITS;
307 break;
308 }
309 case CS8:
310 {
311 rio_dprintk (RIO_DEBUG_PARAM, "8 bit data\n");
312 Cor1 |= COR1_8BITS;
313 break;
314 }
315 }
316
317 if ( TtyP->termios->c_cflag & CSTOPB ) {
318 rio_dprintk (RIO_DEBUG_PARAM, "2 stop bits\n");
319 Cor1 |= COR1_2STOP;
320 }
321 else {
322 rio_dprintk (RIO_DEBUG_PARAM, "1 stop bit\n");
323 Cor1 |= COR1_1STOP;
324 }
325
326 if ( TtyP->termios->c_cflag & PARENB ) {
327 rio_dprintk (RIO_DEBUG_PARAM, "Enable parity\n");
328 Cor1 |= COR1_NORMAL;
329 }
330 else {
331 rio_dprintk (RIO_DEBUG_PARAM, "Disable parity\n");
332 Cor1 |= COR1_NOP;
333 }
334 if ( TtyP->termios->c_cflag & PARODD ) {
335 rio_dprintk (RIO_DEBUG_PARAM, "Odd parity\n");
336 Cor1 |= COR1_ODD;
337 }
338 else {
339 rio_dprintk (RIO_DEBUG_PARAM, "Even parity\n");
340 Cor1 |= COR1_EVEN;
341 }
342
343 /*
344 ** COR 2
345 */
346 if ( TtyP->termios->c_iflag & IXON ) {
347 rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop output control\n");
348 Cor2 |= COR2_IXON;
349 }
350 else {
351 if ( PortP->Config & RIO_IXON ) {
352 rio_dprintk (RIO_DEBUG_PARAM, "Force enable start/stop output control\n");
353 Cor2 |= COR2_IXON;
354 }
355 else
356 rio_dprintk (RIO_DEBUG_PARAM, "IXON has been disabled.\n");
357 }
358
359 if (TtyP->termios->c_iflag & IXANY) {
360 if ( PortP->Config & RIO_IXANY ) {
361 rio_dprintk (RIO_DEBUG_PARAM, "Enable any key to restart output\n");
362 Cor2 |= COR2_IXANY;
363 }
364 else
365 rio_dprintk (RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");
366 }
367
368 if ( TtyP->termios->c_iflag & IXOFF ) {
369 rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");
370 Cor2 |= COR2_IXOFF;
371 }
372
373 if ( TtyP->termios->c_cflag & HUPCL ) {
374 rio_dprintk (RIO_DEBUG_PARAM, "Hangup on last close\n");
375 Cor2 |= COR2_HUPCL;
376 }
377
378 if ( C_CRTSCTS (TtyP)) {
379 rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n");
380 Cor2 |= COR2_CTSFLOW;
381 Cor2 |= COR2_RTSFLOW;
382 } else {
383 rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n");
384 Cor2 &= ~COR2_CTSFLOW;
385 Cor2 &= ~COR2_RTSFLOW;
386 }
387
388
389 if ( TtyP->termios->c_cflag & CLOCAL ) {
390 rio_dprintk (RIO_DEBUG_PARAM, "Local line\n");
391 }
392 else {
393 rio_dprintk (RIO_DEBUG_PARAM, "Possible Modem line\n");
394 }
395
396 /*
397 ** COR 4 (there is no COR 3)
398 */
399 if ( TtyP->termios->c_iflag & IGNBRK ) {
400 rio_dprintk (RIO_DEBUG_PARAM, "Ignore break condition\n");
401 Cor4 |= COR4_IGNBRK;
402 }
403 if ( !(TtyP->termios->c_iflag & BRKINT) ) {
404 rio_dprintk (RIO_DEBUG_PARAM, "Break generates NULL condition\n");
405 Cor4 |= COR4_NBRKINT;
406 } else {
407 rio_dprintk (RIO_DEBUG_PARAM, "Interrupt on break condition\n");
408 }
409
410 if ( TtyP->termios->c_iflag & INLCR ) {
411 rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage return on input\n");
412 Cor4 |= COR4_INLCR;
413 }
414
415 if ( TtyP->termios->c_iflag & IGNCR ) {
416 rio_dprintk (RIO_DEBUG_PARAM, "Ignore carriage return on input\n");
417 Cor4 |= COR4_IGNCR;
418 }
419
420 if ( TtyP->termios->c_iflag & ICRNL ) {
421 rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on input\n");
422 Cor4 |= COR4_ICRNL;
423 }
424 if ( TtyP->termios->c_iflag & IGNPAR ) {
425 rio_dprintk (RIO_DEBUG_PARAM, "Ignore characters with parity errors\n");
426 Cor4 |= COR4_IGNPAR;
427 }
428 if ( TtyP->termios->c_iflag & PARMRK ) {
429 rio_dprintk (RIO_DEBUG_PARAM, "Mark parity errors\n");
430 Cor4 |= COR4_PARMRK;
431 }
432
433 /*
434 ** Set the RAISEMOD flag to ensure that the modem lines are raised
435 ** on reception of a config packet.
436 ** The download code handles the zero baud condition.
437 */
438 Cor4 |= COR4_RAISEMOD;
439
440 /*
441 ** COR 5
442 */
443
444 Cor5 = COR5_CMOE;
445
446 /*
447 ** Set to monitor tbusy/tstop (or not).
448 */
449
450 if (PortP->MonitorTstate)
451 Cor5 |= COR5_TSTATE_ON;
452 else
453 Cor5 |= COR5_TSTATE_OFF;
454
455 /*
456 ** Could set LNE here if you wanted LNext processing. SVR4 will use it.
457 */
458 if ( TtyP->termios->c_iflag & ISTRIP ) {
459 rio_dprintk (RIO_DEBUG_PARAM, "Strip input characters\n");
460 if (! (PortP->State & RIO_TRIAD_MODE)) {
461 Cor5 |= COR5_ISTRIP;
462 }
463 }
464
465 if ( TtyP->termios->c_oflag & ONLCR ) {
466 rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n");
467 if ( PortP->CookMode == COOK_MEDIUM )
468 Cor5 |= COR5_ONLCR;
469 }
470 if ( TtyP->termios->c_oflag & OCRNL ) {
471 rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on output\n");
472 if ( PortP->CookMode == COOK_MEDIUM )
473 Cor5 |= COR5_OCRNL;
474 }
475 if ( ( TtyP->termios->c_oflag & TABDLY) == TAB3 ) {
476 rio_dprintk (RIO_DEBUG_PARAM, "Tab delay 3 set\n");
477 if ( PortP->CookMode == COOK_MEDIUM )
478 Cor5 |= COR5_TAB3;
479 }
480
481 /*
482 ** Flow control bytes.
483 */
484 TxXon = TtyP->termios->c_cc[VSTART];
485 TxXoff = TtyP->termios->c_cc[VSTOP];
486 RxXon = TtyP->termios->c_cc[VSTART];
487 RxXoff = TtyP->termios->c_cc[VSTOP];
488 /*
489 ** LNEXT byte
490 */
491 LNext = 0;
492
493 /*
494 ** Baud rate bytes
495 */
496 rio_dprintk (RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n",
497 TtyP->termios->c_cflag, CBAUD);
498
499 switch (TtyP->termios->c_cflag & CBAUD) {
500#define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break
501 e(50);e(75);e(110);e(134);e(150);e(200);e(300);e(600);e(1200);
502 e(1800);e(2400);e(4800);e(9600);e(19200);e(38400);e(57600);
503 e(115200); /* e(230400);e(460800); e(921600); */
504 }
505
506 /* XXX MIssing conversion table. XXX */
507 /* (TtyP->termios->c_cflag & V_CBAUD); */
508
509 rio_dprintk (RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud);
510
511
512 /*
513 ** Leftovers
514 */
515 if ( TtyP->termios->c_cflag & CREAD )
516 rio_dprintk (RIO_DEBUG_PARAM, "Enable receiver\n");
517#ifdef RCV1EN
518 if ( TtyP->termios->c_cflag & RCV1EN )
519 rio_dprintk (RIO_DEBUG_PARAM, "RCV1EN (?)\n");
520#endif
521#ifdef XMT1EN
522 if ( TtyP->termios->c_cflag & XMT1EN )
523 rio_dprintk (RIO_DEBUG_PARAM, "XMT1EN (?)\n");
524#endif
525#if 0
526 if ( TtyP->termios->c_cflag & LOBLK )
527 rio_dprintk (RIO_DEBUG_PARAM, "LOBLK - JCL output blocks when not current\n");
528#endif
529 if ( TtyP->termios->c_lflag & ISIG )
530 rio_dprintk (RIO_DEBUG_PARAM, "Input character signal generating enabled\n");
531 if ( TtyP->termios->c_lflag & ICANON )
532 rio_dprintk (RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n");
533 if ( TtyP->termios->c_lflag & XCASE )
534 rio_dprintk (RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n");
535 if ( TtyP->termios->c_lflag & ECHO )
536 rio_dprintk (RIO_DEBUG_PARAM, "Enable input echo\n");
537 if ( TtyP->termios->c_lflag & ECHOE )
538 rio_dprintk (RIO_DEBUG_PARAM, "Enable echo erase\n");
539 if ( TtyP->termios->c_lflag & ECHOK )
540 rio_dprintk (RIO_DEBUG_PARAM, "Enable echo kill\n");
541 if ( TtyP->termios->c_lflag & ECHONL )
542 rio_dprintk (RIO_DEBUG_PARAM, "Enable echo newline\n");
543 if ( TtyP->termios->c_lflag & NOFLSH )
544 rio_dprintk (RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n");
545#ifdef TOSTOP
546 if ( TtyP->termios->c_lflag & TOSTOP )
547 rio_dprintk (RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n");
548#endif
549#ifdef XCLUDE
550 if ( TtyP->termios->c_lflag & XCLUDE )
551 rio_dprintk (RIO_DEBUG_PARAM, "Exclusive use of this line\n");
552#endif
553 if ( TtyP->termios->c_iflag & IUCLC )
554 rio_dprintk (RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n");
555 if ( TtyP->termios->c_oflag & OPOST )
556 rio_dprintk (RIO_DEBUG_PARAM, "Enable output post-processing\n");
557 if ( TtyP->termios->c_oflag & OLCUC )
558 rio_dprintk (RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n");
559 if ( TtyP->termios->c_oflag & ONOCR )
560 rio_dprintk (RIO_DEBUG_PARAM, "No carriage return output at column 0\n");
561 if ( TtyP->termios->c_oflag & ONLRET )
562 rio_dprintk (RIO_DEBUG_PARAM, "Newline performs carriage return function\n");
563 if ( TtyP->termios->c_oflag & OFILL )
564 rio_dprintk (RIO_DEBUG_PARAM, "Use fill characters for delay\n");
565 if ( TtyP->termios->c_oflag & OFDEL )
566 rio_dprintk (RIO_DEBUG_PARAM, "Fill character is DEL\n");
567 if ( TtyP->termios->c_oflag & NLDLY )
568 rio_dprintk (RIO_DEBUG_PARAM, "Newline delay set\n");
569 if ( TtyP->termios->c_oflag & CRDLY )
570 rio_dprintk (RIO_DEBUG_PARAM, "Carriage return delay set\n");
571 if ( TtyP->termios->c_oflag & TABDLY )
572 rio_dprintk (RIO_DEBUG_PARAM, "Tab delay set\n");
573#if 0
574 if ( TtyP->termios->c_oflag & BSDLY )
575 rio_dprintk (RIO_DEBUG_PARAM, "Back-space delay set\n");
576 if ( TtyP->termios->c_oflag & VTDLY )
577 rio_dprintk (RIO_DEBUG_PARAM, "Vertical tab delay set\n");
578 if ( TtyP->termios->c_oflag & FFDLY )
579 rio_dprintk (RIO_DEBUG_PARAM, "Form-feed delay set\n");
580#endif
581 /*
582 ** These things are kind of useful in a later life!
583 */
584 PortP->Cor2Copy = Cor2;
585
586 if ( PortP->State & RIO_DELETED ) {
587 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
588 func_exit ();
589
590 return RIO_FAIL;
591 }
592
593 /*
594 ** Actually write the info into the packet to be sent
595 */
596 WBYTE(phb_param_ptr->Cmd, cmd);
597 WBYTE(phb_param_ptr->Cor1, Cor1);
598 WBYTE(phb_param_ptr->Cor2, Cor2);
599 WBYTE(phb_param_ptr->Cor4, Cor4);
600 WBYTE(phb_param_ptr->Cor5, Cor5);
601 WBYTE(phb_param_ptr->TxXon, TxXon);
602 WBYTE(phb_param_ptr->RxXon, RxXon);
603 WBYTE(phb_param_ptr->TxXoff, TxXoff);
604 WBYTE(phb_param_ptr->RxXoff, RxXoff);
605 WBYTE(phb_param_ptr->LNext, LNext);
606 WBYTE(phb_param_ptr->TxBaud, TxBaud);
607 WBYTE(phb_param_ptr->RxBaud, RxBaud);
608
609 /*
610 ** Set the length/command field
611 */
612 WBYTE(PacketP->len , 12 | PKT_CMD_BIT);
613
614 /*
615 ** The packet is formed - now, whack it off
616 ** to its final destination:
617 */
618 add_transmit(PortP);
619 /*
620 ** Count characters transmitted for port statistics reporting
621 */
622 if (PortP->statsGather)
623 PortP->txchars += 12;
624
625 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
626
627 rio_dprintk (RIO_DEBUG_PARAM, "add_transmit returned.\n");
628 /*
629 ** job done.
630 */
631 func_exit ();
632
633 return RIO_SUCCESS;
634}
635
636
637/*
638** We can add another packet to a transmit queue if the packet pointer pointed
639** to by the TxAdd pointer has PKT_IN_USE clear in its address.
640*/
641int
642can_add_transmit(PktP, PortP)
643PKT **PktP;
644struct Port *PortP;
645{
646 register PKT *tp;
647
648 *PktP = tp = (PKT *)RIO_PTR(PortP->Caddr,RWORD(*PortP->TxAdd));
649
650 return !((uint)tp & PKT_IN_USE);
651}
652
653/*
654** To add a packet to the queue, you set the PKT_IN_USE bit in the address,
655** and then move the TxAdd pointer along one position to point to the next
656** packet pointer. You must wrap the pointer from the end back to the start.
657*/
658void
659add_transmit(PortP)
660struct Port *PortP;
661{
662 if (RWORD(*PortP->TxAdd) & PKT_IN_USE) {
663 rio_dprintk (RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!");
664 }
665 WWORD( *(ushort *)PortP->TxAdd, RWORD(*PortP->TxAdd) | PKT_IN_USE);
666 PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart :
667 PortP->TxAdd + 1;
668 WWORD( PortP->PhbP->tx_add , RIO_OFF(PortP->Caddr,PortP->TxAdd) );
669}
670
671/****************************************
672 * Put a packet onto the end of the
673 * free list
674 ****************************************/
675void
676put_free_end(HostP, PktP)
677struct Host *HostP;
678PKT *PktP;
679{
680 FREE_LIST *tmp_pointer;
681 ushort old_end, new_end;
682 unsigned long flags;
683
684 rio_spin_lock_irqsave(&HostP->HostLock, flags);
685
686 /*************************************************
687 * Put a packet back onto the back of the free list
688 *
689 ************************************************/
690
691 rio_dprintk (RIO_DEBUG_PFE, "put_free_end(PktP=%x)\n",(int)PktP);
692
693 if ((old_end=RWORD(HostP->ParmMapP->free_list_end)) != TPNULL) {
694 new_end = RIO_OFF(HostP->Caddr,PktP);
695 tmp_pointer = (FREE_LIST *)RIO_PTR(HostP->Caddr,old_end);
696 WWORD(tmp_pointer->next , new_end );
697 WWORD(((FREE_LIST *)PktP)->prev , old_end);
698 WWORD(((FREE_LIST *)PktP)->next , TPNULL);
699 WWORD(HostP->ParmMapP->free_list_end, new_end);
700 }
701 else { /* First packet on the free list this should never happen! */
702 rio_dprintk (RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
703 WWORD(HostP->ParmMapP->free_list_end , RIO_OFF(HostP->Caddr,PktP));
704 tmp_pointer = (FREE_LIST *)PktP;
705 WWORD(tmp_pointer->prev , TPNULL);
706 WWORD(tmp_pointer->next , TPNULL);
707 }
708 rio_dprintk (RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock);
709 rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
710}
711
712/*
713** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set
714** for the next packet on the queue. It will also set PktP to point to the
715** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
716** then can_remove_receive() returns 0.
717*/
718int
719can_remove_receive(PktP, PortP)
720PKT **PktP;
721struct Port *PortP;
722{
723 if ( RWORD(*PortP->RxRemove) & PKT_IN_USE) {
724 *PktP = (PKT *)RIO_PTR(PortP->Caddr,
725 RWORD(*PortP->RxRemove) & ~PKT_IN_USE);
726 return 1;
727 }
728 return 0;
729}
730
731/*
732** To remove a packet from the receive queue you clear its PKT_IN_USE bit,
733** and then bump the pointers. Once the pointers get to the end, they must
734** be wrapped back to the start.
735*/
736void
737remove_receive(PortP)
738struct Port *PortP;
739{
740 WWORD( *PortP->RxRemove, RWORD(*PortP->RxRemove) & ~PKT_IN_USE );
741 PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart :
742 PortP->RxRemove + 1;
743 WWORD( PortP->PhbP->rx_remove , RIO_OFF(PortP->Caddr, PortP->RxRemove) );
744}
diff --git a/drivers/char/rio/riopcicopy.c b/drivers/char/rio/riopcicopy.c
new file mode 100644
index 000000000000..2ea99a60aa32
--- /dev/null
+++ b/drivers/char/rio/riopcicopy.c
@@ -0,0 +1,8 @@
1
2/* Yeah. We have copyright on this one. Sure. */
3
4void rio_pcicopy( char *from, char *to, int amount)
5{
6 while ( amount-- )
7 *to++ = *from++;
8}
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
new file mode 100644
index 000000000000..106b31f48a21
--- /dev/null
+++ b/drivers/char/rio/rioroute.c
@@ -0,0 +1,1238 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : rioroute.c
24** SID : 1.3
25** Last Modified : 11/6/98 10:33:46
26** Retrieved : 11/6/98 10:33:50
27**
28** ident @(#)rioroute.c 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32#ifdef SCCS_LABELS
33static char *_rioroute_c_sccs_ = "@(#)rioroute.c 1.3";
34#endif
35
36#include <linux/module.h>
37#include <linux/slab.h>
38#include <linux/errno.h>
39#include <asm/io.h>
40#include <asm/system.h>
41#include <asm/string.h>
42#include <asm/semaphore.h>
43#include <asm/uaccess.h>
44
45#include <linux/termios.h>
46#include <linux/serial.h>
47
48#include <linux/generic_serial.h>
49
50
51#include "linux_compat.h"
52#include "rio_linux.h"
53#include "typdef.h"
54#include "pkt.h"
55#include "daemon.h"
56#include "rio.h"
57#include "riospace.h"
58#include "top.h"
59#include "cmdpkt.h"
60#include "map.h"
61#include "riotypes.h"
62#include "rup.h"
63#include "port.h"
64#include "riodrvr.h"
65#include "rioinfo.h"
66#include "func.h"
67#include "errors.h"
68#include "pci.h"
69
70#include "parmmap.h"
71#include "unixrup.h"
72#include "board.h"
73#include "host.h"
74#include "error.h"
75#include "phb.h"
76#include "link.h"
77#include "cmdblk.h"
78#include "route.h"
79#include "control.h"
80#include "cirrus.h"
81#include "rioioctl.h"
82#include "param.h"
83#include "list.h"
84#include "sam.h"
85
86static int RIOCheckIsolated(struct rio_info *, struct Host *, uint);
87static int RIOIsolate(struct rio_info *, struct Host *, uint);
88static int RIOCheck(struct Host *, uint);
89static void RIOConCon(struct rio_info *, struct Host *, uint, uint, uint, uint, int);
90
91
92/*
93** Incoming on the ROUTE_RUP
94** I wrote this while I was tired. Forgive me.
95*/
96int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP )
97{
98 struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
99 struct PktCmd_M *PktReplyP;
100 struct CmdBlk *CmdBlkP;
101 struct Port *PortP;
102 struct Map *MapP;
103 struct Top *TopP;
104 int ThisLink, ThisLinkMin, ThisLinkMax;
105 int port;
106 int Mod, Mod1, Mod2;
107 ushort RtaType;
108 uint RtaUniq;
109 uint ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */
110 uint OldUnit, NewUnit, OldLink, NewLink;
111 char *MyType, *MyName;
112 int Lies;
113 unsigned long flags;
114
115#ifdef STACK
116 RIOStackCheck("RIORouteRup");
117#endif
118#ifdef CHECK
119 CheckPacketP(PacketP);
120 CheckHostP(HostP);
121 CheckRup(Rup);
122 CheckHost(Host);
123#endif
124 /*
125 ** Is this unit telling us it's current link topology?
126 */
127 if ( RBYTE(PktCmdP->Command) == ROUTE_TOPOLOGY )
128 {
129 MapP = HostP->Mapping;
130
131 /*
132 ** The packet can be sent either by the host or by an RTA.
133 ** If it comes from the host, then we need to fill in the
134 ** Topology array in the host structure. If it came in
135 ** from an RTA then we need to fill in the Mapping structure's
136 ** Topology array for the unit.
137 */
138 if ( Rup >= (ushort)MAX_RUP )
139 {
140 ThisUnit = HOST_ID;
141 TopP = HostP->Topology;
142 MyType = "Host";
143 MyName = HostP->Name;
144 ThisLinkMin = ThisLinkMax = Rup - MAX_RUP;
145 }
146 else
147 {
148 ThisUnit = Rup+1;
149 TopP = HostP->Mapping[Rup].Topology;
150 MyType = "RTA";
151 MyName = HostP->Mapping[Rup].Name;
152 ThisLinkMin = 0;
153 ThisLinkMax = LINKS_PER_UNIT - 1;
154 }
155
156 /*
157 ** Lies will not be tolerated.
158 ** If any pair of links claim to be connected to the same
159 ** place, then ignore this packet completely.
160 */
161 Lies = 0;
162 for ( ThisLink=ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++)
163 {
164 /*
165 ** it won't lie about network interconnect, total disconnects
166 ** and no-IDs. (or at least, it doesn't *matter* if it does)
167 */
168 if ( RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) > (ushort)MAX_RUP )
169 continue;
170
171 for ( NewLink=ThisLinkMin; NewLink < ThisLink; NewLink++ )
172 {
173 if ( (RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) ==
174 RBYTE(PktCmdP->RouteTopology[NewLink].Unit)) &&
175 (RBYTE(PktCmdP->RouteTopology[ThisLink].Link) ==
176 RBYTE(PktCmdP->RouteTopology[NewLink].Link)) )
177 {
178 Lies++;
179 }
180 }
181 }
182
183 if ( Lies )
184 {
185 rio_dprintk (RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n",Lies);
186 rio_dprintk (RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n",
187 RBYTE(PktCmdP->RouteTopology[0].Unit),
188 'A'+RBYTE(PktCmdP->RouteTopology[0].Link),
189 RBYTE(PktCmdP->RouteTopology[1].Unit),
190 'A'+RBYTE(PktCmdP->RouteTopology[1].Link),
191 RBYTE(PktCmdP->RouteTopology[2].Unit),
192 'A'+RBYTE(PktCmdP->RouteTopology[2].Link),
193 RBYTE(PktCmdP->RouteTopology[3].Unit),
194 'A'+RBYTE(PktCmdP->RouteTopology[3].Link));
195 return TRUE;
196 }
197
198 /*
199 ** now, process each link.
200 */
201 for ( ThisLink=ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++)
202 {
203 /*
204 ** this is what it was connected to
205 */
206 OldUnit = TopP[ThisLink].Unit;
207 OldLink = TopP[ThisLink].Link;
208
209 /*
210 ** this is what it is now connected to
211 */
212 NewUnit = RBYTE(PktCmdP->RouteTopology[ThisLink].Unit);
213 NewLink = RBYTE(PktCmdP->RouteTopology[ThisLink].Link);
214
215 if ( OldUnit != NewUnit || OldLink != NewLink )
216 {
217 /*
218 ** something has changed!
219 */
220
221 if ( NewUnit > MAX_RUP &&
222 NewUnit != ROUTE_DISCONNECT &&
223 NewUnit != ROUTE_NO_ID &&
224 NewUnit != ROUTE_INTERCONNECT )
225 {
226 rio_dprintk (RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n",
227 MyType,
228 MyName,
229 NewUnit,
230 NewLink);
231 }
232 else
233 {
234 /*
235 ** put the new values in
236 */
237 TopP[ThisLink].Unit = NewUnit;
238 TopP[ThisLink].Link = NewLink;
239
240 RIOSetChange(p);
241
242 if ( OldUnit <= MAX_RUP )
243 {
244 /*
245 ** If something has become bust, then re-enable them messages
246 */
247 if (! p->RIONoMessage)
248 RIOConCon(p,HostP,ThisUnit,ThisLink,OldUnit,OldLink,DISCONNECT);
249 }
250
251 if ( ( NewUnit <= MAX_RUP ) && !p->RIONoMessage )
252 RIOConCon(p,HostP,ThisUnit,ThisLink,NewUnit,NewLink,CONNECT);
253
254 if ( NewUnit == ROUTE_NO_ID )
255 rio_dprintk (RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n",
256 MyType,MyName,'A'+ThisLink);
257
258 if ( NewUnit == ROUTE_INTERCONNECT )
259 {
260 if (! p->RIONoMessage)
261 cprintf("%s '%s' (%c) is connected to another network.\n", MyType,MyName,'A'+ThisLink);
262 }
263
264 /*
265 ** perform an update for 'the other end', so that these messages
266 ** only appears once. Only disconnect the other end if it is pointing
267 ** at us!
268 */
269 if ( OldUnit == HOST_ID )
270 {
271 if ( HostP->Topology[OldLink].Unit == ThisUnit &&
272 HostP->Topology[OldLink].Link == ThisLink )
273 {
274 rio_dprintk (RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A');
275 HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT;
276 HostP->Topology[OldLink].Link = NO_LINK;
277 }
278 else
279 {
280 rio_dprintk (RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n",
281 OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
282 }
283 }
284 else if ( OldUnit <= MAX_RUP )
285 {
286 if ( HostP->Mapping[OldUnit-1].Topology[OldLink].Unit == ThisUnit &&
287 HostP->Mapping[OldUnit-1].Topology[OldLink].Link == ThisLink )
288 {
289 rio_dprintk (RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n",
290 HostP->Mapping[OldUnit-1].Name,OldLink+'A');
291 HostP->Mapping[OldUnit-1].Topology[OldLink].Unit=ROUTE_DISCONNECT;
292 HostP->Mapping[OldUnit-1].Topology[OldLink].Link=NO_LINK;
293 }
294 else
295 {
296 rio_dprintk (RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n",
297 HostP->Mapping[OldUnit-1].Name,OldLink+'A',
298 HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
299 }
300 }
301 if ( NewUnit == HOST_ID )
302 {
303 rio_dprintk (RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n",
304 NewLink+'A',MyName,ThisLink+'A');
305 HostP->Topology[NewLink].Unit = ThisUnit;
306 HostP->Topology[NewLink].Link = ThisLink;
307 }
308 else if ( NewUnit <= MAX_RUP )
309 {
310 rio_dprintk (RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n",
311 HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A');
312 HostP->Mapping[NewUnit-1].Topology[NewLink].Unit=ThisUnit;
313 HostP->Mapping[NewUnit-1].Topology[NewLink].Link=ThisLink;
314 }
315 }
316 RIOSetChange(p);
317 RIOCheckIsolated(p, HostP, OldUnit );
318 }
319 }
320 return TRUE;
321 }
322
323 /*
324 ** The only other command we recognise is a route_request command
325 */
326 if ( RBYTE(PktCmdP->Command) != ROUTE_REQUEST )
327 {
328 rio_dprintk (RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %d ROUTE_RUP\n",
329 RBYTE(PktCmdP->Command),Rup,(int)HostP);
330 return TRUE;
331 }
332
333 RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) +
334 (RBYTE(PktCmdP->UniqNum[1]) << 8) +
335 (RBYTE(PktCmdP->UniqNum[2]) << 16) +
336 (RBYTE(PktCmdP->UniqNum[3]) << 24);
337
338 /*
339 ** Determine if 8 or 16 port RTA
340 */
341 RtaType = GetUnitType(RtaUniq);
342
343 rio_dprintk (RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq);
344
345 Mod = RBYTE(PktCmdP->ModuleTypes);
346 Mod1 = LONYBLE(Mod);
347 if (RtaType == TYPE_RTA16)
348 {
349 /*
350 ** Only one ident is set for a 16 port RTA. To make compatible
351 ** with 8 port, set 2nd ident in Mod2 to the same as Mod1.
352 */
353 Mod2 = Mod1;
354 rio_dprintk (RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n",
355 p->RIOModuleTypes[Mod1].Name);
356 }
357 else
358 {
359 Mod2 = HINYBLE(Mod);
360 rio_dprintk (RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n",
361 p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name);
362 }
363
364 if ( RtaUniq == 0xffffffff )
365 {
366 ShowPacket( DBG_SPECIAL, PacketP );
367 }
368
369 /*
370 ** try to unhook a command block from the command free list.
371 */
372 if ( !(CmdBlkP = RIOGetCmdBlk()) )
373 {
374 rio_dprintk (RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n");
375 return 0;
376 }
377
378 /*
379 ** Fill in the default info on the command block
380 */
381 CmdBlkP->Packet.dest_unit = Rup;
382 CmdBlkP->Packet.dest_port = ROUTE_RUP;
383 CmdBlkP->Packet.src_unit = HOST_ID;
384 CmdBlkP->Packet.src_port = ROUTE_RUP;
385 CmdBlkP->Packet.len = PKT_CMD_BIT | 1;
386 CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL;
387 PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data;
388
389 if (! RIOBootOk(p, HostP, RtaUniq))
390 {
391 rio_dprintk (RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n",
392 RtaUniq);
393 PktReplyP->Command = ROUTE_FOAD;
394 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
395 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
396 return TRUE;
397 }
398
399 /*
400 ** Check to see if the RTA is configured for this host
401 */
402 for ( ThisUnit=0; ThisUnit<MAX_RUP; ThisUnit++ )
403 {
404 rio_dprintk (RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n",
405 ThisUnit,
406 HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ?
407 "Slot-In-Use":"Not In Use",
408 HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ?
409 "Slot-Tentative":"Not Tentative",
410 HostP->Mapping[ThisUnit].RtaUniqueNum);
411
412 /*
413 ** We have an entry for it.
414 */
415 if ( (HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) &&
416 (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq) )
417 {
418 if (RtaType == TYPE_RTA16)
419 {
420 ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1;
421 rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n",
422 RtaUniq,ThisUnit,ThisUnit2);
423 }
424 else
425 rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n",
426 RtaUniq,ThisUnit);
427 /*
428 ** If we have no knowledge of booting it, then the host has
429 ** been re-booted, and so we must kill the RTA, so that it
430 ** will be booted again (potentially with new bins)
431 ** and it will then re-ask for an ID, which we will service.
432 */
433 if ( (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) &&
434 !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED) )
435 {
436 if ( !(HostP->Mapping[ThisUnit].Flags & MSG_DONE) )
437 {
438 if ( !p->RIONoMessage )
439 cprintf("RTA '%s' is being updated.\n",HostP->Mapping[ThisUnit].Name);
440 HostP->Mapping[ThisUnit].Flags |= MSG_DONE;
441 }
442 PktReplyP->Command = ROUTE_FOAD;
443 HostP->Copy("RT_FOAD",PktReplyP->CommandText,7);
444 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
445 return TRUE;
446 }
447
448 /*
449 ** Send the ID (entry) to this RTA. The ID number is implicit as
450 ** the offset into the table. It is worth noting at this stage
451 ** that offset zero in the table contains the entries for the
452 ** RTA with ID 1!!!!
453 */
454 PktReplyP->Command = ROUTE_ALLOCATE;
455 PktReplyP->IDNum = ThisUnit+1;
456 if (RtaType == TYPE_RTA16)
457 {
458 if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE)
459 /*
460 ** Adjust the phb and tx pkt dest_units for 2nd block of 8
461 ** only if the RTA has ports associated (SLOT_IN_USE)
462 */
463 RIOFixPhbs(p, HostP, ThisUnit2);
464 PktReplyP->IDNum2 = ThisUnit2+1;
465 rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n",
466 HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2);
467 }
468 else
469 {
470 PktReplyP->IDNum2 = ROUTE_NO_ID;
471 rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n",
472 HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum);
473 }
474 HostP->Copy("RT_ALLOCAT",PktReplyP->CommandText,10);
475
476 RIOQueueCmdBlk( HostP, Rup, CmdBlkP);
477
478 /*
479 ** If this is a freshly booted RTA, then we need to re-open
480 ** the ports, if any where open, so that data may once more
481 ** flow around the system!
482 */
483 if ( (HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) &&
484 (HostP->Mapping[ThisUnit].SysPort != NO_PORT) )
485 {
486 /*
487 ** look at the ports associated with this beast and
488 ** see if any where open. If they was, then re-open
489 ** them, using the info from the tty flags.
490 */
491 for ( port=0; port<PORTS_PER_RTA; port++ )
492 {
493 PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort];
494 if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
495 {
496 rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
497 rio_spin_lock_irqsave(&PortP->portSem, flags);
498 PortP->MagicFlags |= MAGIC_REBOOT;
499 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
500 }
501 }
502 if (RtaType == TYPE_RTA16)
503 {
504 for ( port=0; port<PORTS_PER_RTA; port++ )
505 {
506 PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort];
507 if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
508 {
509 rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
510 rio_spin_lock_irqsave(&PortP->portSem, flags);
511 PortP->MagicFlags |= MAGIC_REBOOT;
512 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
513 }
514 }
515 }
516 }
517
518 /*
519 ** keep a copy of the module types!
520 */
521 HostP->UnixRups[ThisUnit].ModTypes = Mod;
522 if (RtaType == TYPE_RTA16)
523 HostP->UnixRups[ThisUnit2].ModTypes = Mod;
524
525 /*
526 ** If either of the modules on this unit is read-only or write-only
527 ** or none-xprint, then we need to transfer that info over to the
528 ** relevant ports.
529 */
530 if ( HostP->Mapping[ThisUnit].SysPort != NO_PORT )
531 {
532 for ( port=0; port<PORTS_PER_MODULE; port++ )
533 {
534 p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;
535 p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config |=
536 p->RIOModuleTypes[Mod1].Flags[port];
537 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;
538 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port];
539 }
540 if (RtaType == TYPE_RTA16)
541 {
542 for ( port=0; port<PORTS_PER_MODULE; port++ )
543 {
544 p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK;
545 p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port];
546 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK;
547 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port];
548 }
549 }
550 }
551
552 /*
553 ** Job done, get on with the interrupts!
554 */
555 return TRUE;
556 }
557 }
558 /*
559 ** There is no table entry for this RTA at all.
560 **
561 ** Lets check to see if we actually booted this unit - if not,
562 ** then we reset it and it will go round the loop of being booted
563 ** we can then worry about trying to fit it into the table.
564 */
565 for ( ThisUnit=0; ThisUnit<HostP->NumExtraBooted; ThisUnit++ )
566 if ( HostP->ExtraUnits[ThisUnit] == RtaUniq )
567 break;
568 if ( ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS )
569 {
570 /*
571 ** if the unit wasn't in the table, and the table wasn't full, then
572 ** we reset the unit, because we didn't boot it.
573 ** However, if the table is full, it could be that we did boot
574 ** this unit, and so we won't reboot it, because it isn't really
575 ** all that disasterous to keep the old bins in most cases. This
576 ** is a rather tacky feature, but we are on the edge of reallity
577 ** here, because the implication is that someone has connected
578 ** 16+MAX_EXTRA_UNITS onto one host.
579 */
580 static int UnknownMesgDone = 0;
581
582 if ( !UnknownMesgDone )
583 {
584 if (! p->RIONoMessage)
585 cprintf("One or more unknown RTAs are being updated.\n");
586 UnknownMesgDone = 1;
587 }
588
589 PktReplyP->Command = ROUTE_FOAD;
590 HostP->Copy("RT_FOAD",PktReplyP->CommandText,7);
591 }
592 else
593 {
594 /*
595 ** we did boot it (as an extra), and there may now be a table
596 ** slot free (because of a delete), so we will try to make
597 ** a tentative entry for it, so that the configurator can see it
598 ** and fill in the details for us.
599 */
600 if (RtaType == TYPE_RTA16)
601 {
602 if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0)
603 {
604 RIODefaultName(p, HostP, ThisUnit);
605 FillSlot(ThisUnit, ThisUnit2, RtaUniq, HostP);
606 }
607 }
608 else
609 {
610 if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0)
611 {
612 RIODefaultName(p, HostP, ThisUnit);
613 FillSlot(ThisUnit, 0, RtaUniq, HostP);
614 }
615 }
616 PktReplyP->Command = ROUTE_USED;
617 HostP->Copy("RT_USED",PktReplyP->CommandText,7);
618 }
619 RIOQueueCmdBlk( HostP, Rup, CmdBlkP);
620 return TRUE;
621}
622
623
624void
625RIOFixPhbs(p, HostP, unit)
626struct rio_info *p;
627struct Host *HostP;
628uint unit;
629{
630 ushort link, port;
631 struct Port *PortP;
632 unsigned long flags;
633 int PortN = HostP->Mapping[unit].SysPort;
634
635 rio_dprintk (RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN);
636
637 if (PortN != -1) {
638 ushort dest_unit = HostP->Mapping[unit].ID2;
639
640 /*
641 ** Get the link number used for the 1st 8 phbs on this unit.
642 */
643 PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort];
644
645 link = RWORD(PortP->PhbP->link);
646
647 for (port = 0; port < PORTS_PER_RTA; port++, PortN++) {
648 ushort dest_port = port + 8;
649#if 0
650 uint PktInt;
651#endif
652 WORD *TxPktP;
653 PKT *Pkt;
654
655 PortP = p->RIOPortp[PortN];
656
657 rio_spin_lock_irqsave(&PortP->portSem, flags);
658 /*
659 ** If RTA is not powered on, the tx packets will be
660 ** unset, so go no further.
661 */
662 if (PortP->TxStart == 0) {
663 rio_dprintk (RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");
664 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
665 break;
666 }
667
668 /*
669 ** For the second slot of a 16 port RTA, the driver needs to
670 ** sort out the phb to port mappings. The dest_unit for this
671 ** group of 8 phbs is set to the dest_unit of the accompanying
672 ** 8 port block. The dest_port of the second unit is set to
673 ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port
674 ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6
675 ** (being the second map ID) will be sent to dest_unit 5, port
676 ** 14. When this RTA is deleted, dest_unit for ID 6 will be
677 ** restored, and the dest_port will be reduced by 8.
678 ** Transmit packets also have a destination field which needs
679 ** adjusting in the same manner.
680 ** Note that the unit/port bytes in 'dest' are swapped.
681 ** We also need to adjust the phb and rup link numbers for the
682 ** second block of 8 ttys.
683 */
684 for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {
685 /*
686 ** *TxPktP is the pointer to the transmit packet on the host
687 ** card. This needs to be translated into a 32 bit pointer
688 ** so it can be accessed from the driver.
689 */
690 Pkt = (PKT *) RIO_PTR(HostP->Caddr,RINDW(TxPktP));
691
692 /*
693 ** If the packet is used, reset it.
694 */
695 Pkt = (PKT *)((uint)Pkt & ~PKT_IN_USE);
696 WBYTE(Pkt->dest_unit, dest_unit);
697 WBYTE(Pkt->dest_port, dest_port);
698 }
699 rio_dprintk (RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n",
700 RWORD(PortP->PhbP->destination) & 0xff,
701 (RWORD(PortP->PhbP->destination) >> 8) & 0xff,
702 dest_unit, dest_port);
703 WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8));
704 WWORD(PortP->PhbP->link, link);
705
706 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
707 }
708 /*
709 ** Now make sure the range of ports to be serviced includes
710 ** the 2nd 8 on this 16 port RTA.
711 */
712 if (link > 3) return;
713 if (((unit * 8) + 7) > RWORD(HostP->LinkStrP[link].last_port)) {
714 rio_dprintk (RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7);
715 WWORD(HostP->LinkStrP[link].last_port, (unit * 8) + 7);
716 }
717 }
718}
719
720/*
721** Check to see if the new disconnection has isolated this unit.
722** If it has, then invalidate all its link information, and tell
723** the world about it. This is done to ensure that the configurator
724** only gets up-to-date information about what is going on.
725*/
726static int
727RIOCheckIsolated(p, HostP, UnitId)
728struct rio_info * p;
729struct Host *HostP;
730uint UnitId;
731{
732 unsigned long flags;
733 rio_spin_lock_irqsave(&HostP->HostLock, flags);
734
735#ifdef CHECK
736 CheckHostP( HostP );
737 CheckUnitId( UnitId );
738#endif
739 if ( RIOCheck( HostP, UnitId ) ) {
740 rio_dprintk (RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId);
741 rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
742 return(0);
743 }
744
745 RIOIsolate(p, HostP, UnitId );
746 RIOSetChange(p);
747 rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
748 return 1;
749}
750
751/*
752** Invalidate all the link interconnectivity of this unit, and of
753** all the units attached to it. This will mean that the entire
754** subnet will re-introduce itself.
755*/
756static int
757RIOIsolate(p, HostP, UnitId)
758struct rio_info * p;
759struct Host * HostP;
760uint UnitId;
761{
762 uint link, unit;
763
764#ifdef CHECK
765 CheckHostP( HostP );
766 CheckUnitId( UnitId );
767#endif
768 UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */
769
770 if ( UnitId >= MAX_RUP ) /* dontcha just lurv unsigned maths! */
771 return(0);
772
773 if ( HostP->Mapping[UnitId].Flags & BEEN_HERE )
774 return(0);
775
776 HostP->Mapping[UnitId].Flags |= BEEN_HERE;
777
778 if ( p->RIOPrintDisabled == DO_PRINT )
779 rio_dprintk (RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name);
780
781 for ( link=0; link<LINKS_PER_UNIT; link++) {
782 unit = HostP->Mapping[UnitId].Topology[link].Unit;
783 HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT;
784 HostP->Mapping[UnitId].Topology[link].Link = NO_LINK;
785 RIOIsolate(p, HostP, unit );
786 }
787 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE;
788 return 1;
789}
790
791static int
792RIOCheck(HostP, UnitId)
793struct Host *HostP;
794uint UnitId;
795{
796 unsigned char link;
797
798#ifdef CHECK
799 CheckHostP( HostP );
800 CheckUnitId( UnitId );
801#endif
802/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */
803 rio_dprintk (RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId);
804
805 if ( UnitId == HOST_ID ) {
806 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */
807 return 1;
808 }
809
810 UnitId--;
811
812 if ( UnitId >= MAX_RUP ) {
813 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */
814 return 0;
815 }
816
817 for ( link=0; link<LINKS_PER_UNIT; link++ ) {
818 if ( HostP->Mapping[UnitId].Topology[link].Unit==HOST_ID ) {
819 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n",
820 UnitId, 'A'+link)); */
821 return 1;
822 }
823 }
824
825 if ( HostP->Mapping[UnitId].Flags & BEEN_HERE ) {
826 /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */
827 return 0;
828 }
829
830 HostP->Mapping[UnitId].Flags |= BEEN_HERE;
831
832 for ( link=0; link < LINKS_PER_UNIT; link++ ) {
833 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */
834 if ( RIOCheck( HostP, HostP->Mapping[UnitId].Topology[link].Unit ) ) {
835 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */
836 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE;
837 return 1;
838 }
839 }
840
841 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE;
842
843 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */
844
845 return 0;
846}
847
848/*
849** Returns the type of unit (host, 16/8 port RTA)
850*/
851
852uint
853GetUnitType(Uniq)
854uint Uniq;
855{
856 switch ( (Uniq >> 28) & 0xf)
857 {
858 case RIO_AT:
859 case RIO_MCA:
860 case RIO_EISA:
861 case RIO_PCI:
862 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Host\n");
863 return(TYPE_HOST);
864 case RIO_RTA_16:
865 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n");
866 return(TYPE_RTA16);
867 case RIO_RTA:
868 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n");
869 return(TYPE_RTA8);
870 default :
871 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n");
872 return(99);
873 }
874}
875
876int
877RIOSetChange(p)
878struct rio_info * p;
879{
880 if ( p->RIOQuickCheck != NOT_CHANGED )
881 return(0);
882 p->RIOQuickCheck = CHANGED;
883 if ( p->RIOSignalProcess ) {
884 rio_dprintk (RIO_DEBUG_ROUTE, "Send SIG-HUP");
885 /*
886 psignal( RIOSignalProcess, SIGHUP );
887 */
888 }
889 return(0);
890}
891
892static void
893RIOConCon(p, HostP, FromId, FromLink, ToId, ToLink, Change)
894struct rio_info * p;
895struct Host *HostP;
896uint FromId;
897uint FromLink;
898uint ToId;
899uint ToLink;
900int Change;
901{
902 char *FromName;
903 char *FromType;
904 char *ToName;
905 char *ToType;
906 unsigned int tp;
907
908/*
909** 15.10.1998 ARG - ESIL 0759
910** (Part) fix for port being trashed when opened whilst RTA "disconnected"
911**
912** What's this doing in here anyway ?
913** It was causing the port to be 'unmapped' if opened whilst RTA "disconnected"
914**
915** 09.12.1998 ARG - ESIL 0776 - part fix
916** Okay, We've found out what this was all about now !
917** Someone had botched this to use RIOHalted to indicated the number of RTAs
918** 'disconnected'. The value in RIOHalted was then being used in the
919** 'RIO_QUICK_CHECK' ioctl. A none zero value indicating that a least one RTA
920** is 'disconnected'. The change was put in to satisfy a customer's needs.
921** Having taken this bit of code out 'RIO_QUICK_CHECK' now no longer works for
922** the customer.
923**
924 if (Change == CONNECT) {
925 if (p->RIOHalted) p->RIOHalted --;
926 }
927 else {
928 p->RIOHalted ++;
929 }
930**
931** So - we need to implement it slightly differently - a new member of the
932** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA
933** connections and disconnections.
934*/
935 if (Change == CONNECT) {
936 if (p->RIORtaDisCons) p->RIORtaDisCons--;
937 }
938 else {
939 p->RIORtaDisCons++;
940 }
941
942 if ( p->RIOPrintDisabled == DONT_PRINT )
943 return;
944
945 if ( FromId > ToId ) {
946 tp = FromId;
947 FromId = ToId;
948 ToId = tp;
949 tp = FromLink;
950 FromLink = ToLink;
951 ToLink = tp;
952 }
953
954 FromName = FromId ? HostP->Mapping[FromId-1].Name : HostP->Name;
955 FromType = FromId ? "RTA" : "HOST";
956 ToName = ToId ? HostP->Mapping[ToId-1].Name : HostP->Name;
957 ToType = ToId ? "RTA" : "HOST";
958
959 rio_dprintk (RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
960 FromType, FromName, 'A'+FromLink,
961 ToType, ToName, 'A'+ToLink,
962 (Change==CONNECT) ? "established" : "disconnected");
963 cprintf("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
964 FromType, FromName, 'A'+FromLink,
965 ToType, ToName, 'A'+ToLink,
966 (Change==CONNECT) ? "established" : "disconnected");
967}
968
969/*
970** RIORemoveFromSavedTable :
971**
972** Delete and RTA entry from the saved table given to us
973** by the configuration program.
974*/
975static int
976RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap)
977{
978 int entry;
979
980 /*
981 ** We loop for all entries even after finding an entry and
982 ** zeroing it because we may have two entries to delete if
983 ** it's a 16 port RTA.
984 */
985 for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++)
986 {
987 if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum)
988 {
989 bzero((caddr_t)&p->RIOSavedTable[entry], sizeof(struct Map));
990 }
991 }
992 return 0;
993}
994
995
996/*
997** RIOCheckDisconnected :
998**
999** Scan the unit links to and return zero if the unit is completely
1000** disconnected.
1001*/
1002static int
1003RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
1004{
1005 int link;
1006
1007
1008 rio_dprintk (RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit);
1009 /*
1010 ** If the slot is tentative and does not belong to the
1011 ** second half of a 16 port RTA then scan to see if
1012 ** is disconnected.
1013 */
1014 for (link = 0; link < LINKS_PER_UNIT; link++)
1015 {
1016 if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT)
1017 break;
1018 }
1019
1020 /*
1021 ** If not all links are disconnected then we can forget about it.
1022 */
1023 if (link < LINKS_PER_UNIT)
1024 return 1;
1025
1026#if NEED_TO_FIX_THIS
1027 /* Ok so all the links are disconnected. But we may have only just
1028 ** made this slot tentative and not yet received a topology update.
1029 ** Lets check how long ago we made it tentative.
1030 */
1031 rio_dprintk (RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit);
1032 if (drv_getparm(LBOLT, (ulong_t *) &current_time))
1033 rio_dprintk (RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n");
1034
1035 elapse_time = current_time - TentTime[unit];
1036 rio_dprintk (RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n",
1037 elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time));
1038 if (drv_hztousec(elapse_time) < WAIT_TO_FINISH)
1039 {
1040 rio_dprintk (RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n",
1041 unit, drv_hztousec(elapse_time));
1042 return 1;
1043 }
1044#endif
1045
1046 /*
1047 ** We have found an usable slot.
1048 ** If it is half of a 16 port RTA then delete the other half.
1049 */
1050 if (HostP->Mapping[unit].ID2 != 0)
1051 {
1052 int nOther = (HostP->Mapping[unit].ID2) -1;
1053
1054 rio_dprintk (RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther);
1055 bzero((caddr_t)&HostP->Mapping[nOther], sizeof(struct Map));
1056 }
1057 RIORemoveFromSavedTable(p, &HostP->Mapping[unit]);
1058
1059 return 0;
1060}
1061
1062
1063/*
1064** RIOFindFreeID :
1065**
1066** This function scans the given host table for either one
1067** or two free unit ID's.
1068*/
1069int
1070RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
1071{
1072 int unit,tempID;
1073
1074 /*
1075 ** Initialise the ID's to MAX_RUP.
1076 ** We do this to make the loop for setting the ID's as simple as
1077 ** possible.
1078 */
1079 *pID1 = MAX_RUP;
1080 if (pID2 != NULL)
1081 *pID2 = MAX_RUP;
1082
1083 /*
1084 ** Scan all entries of the host mapping table for free slots.
1085 ** We scan for free slots first and then if that is not successful
1086 ** we start all over again looking for tentative slots we can re-use.
1087 */
1088 for (unit = 0; unit < MAX_RUP; unit++)
1089 {
1090 rio_dprintk (RIO_DEBUG_ROUTE, "Scanning unit %d\n",unit);
1091 /*
1092 ** If the flags are zero then the slot is empty.
1093 */
1094 if (HostP->Mapping[unit].Flags == 0)
1095 {
1096 rio_dprintk (RIO_DEBUG_ROUTE, " This slot is empty.\n");
1097 /*
1098 ** If we haven't allocated the first ID then do it now.
1099 */
1100 if (*pID1 == MAX_RUP)
1101 {
1102 rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit);
1103 *pID1 = unit;
1104
1105 /*
1106 ** If the second ID is not needed then we can return
1107 ** now.
1108 */
1109 if (pID2 == NULL)
1110 return 0;
1111 }
1112 else
1113 {
1114 /*
1115 ** Allocate the second slot and return.
1116 */
1117 rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit);
1118 *pID2 = unit;
1119 return 0;
1120 }
1121 }
1122 }
1123
1124 /*
1125 ** If we manage to come out of the free slot loop then we
1126 ** need to start all over again looking for tentative slots
1127 ** that we can re-use.
1128 */
1129 rio_dprintk (RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n");
1130 for (unit = 0; unit < MAX_RUP; unit++)
1131 {
1132 if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) ||
1133 (HostP->Mapping[unit].Flags == 0)) && !
1134 (HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT ))
1135 {
1136 rio_dprintk (RIO_DEBUG_ROUTE, " Slot %d looks promising.\n",unit);
1137
1138 if(unit == *pID1)
1139 {
1140 rio_dprintk (RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n");
1141 continue;
1142 }
1143
1144 /*
1145 ** Slot is Tentative or Empty, but not a tentative second
1146 ** slot of a 16 porter.
1147 ** Attempt to free up this slot (and its parnter if
1148 ** it is a 16 port slot. The second slot will become
1149 ** empty after a call to RIOFreeDisconnected so thats why
1150 ** we look for empty slots above as well).
1151 */
1152 if (HostP->Mapping[unit].Flags != 0)
1153 if (RIOFreeDisconnected(p, HostP, unit) != 0)
1154 continue;
1155 /*
1156 ** If we haven't allocated the first ID then do it now.
1157 */
1158 if (*pID1 == MAX_RUP)
1159 {
1160 rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit);
1161 *pID1 = unit;
1162
1163 /*
1164 ** Clear out this slot now that we intend to use it.
1165 */
1166 bzero(&HostP->Mapping[unit], sizeof(struct Map));
1167
1168 /*
1169 ** If the second ID is not needed then we can return
1170 ** now.
1171 */
1172 if (pID2 == NULL)
1173 return 0;
1174 }
1175 else
1176 {
1177 /*
1178 ** Allocate the second slot and return.
1179 */
1180 rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n",
1181 unit);
1182 *pID2 = unit;
1183
1184 /*
1185 ** Clear out this slot now that we intend to use it.
1186 */
1187 bzero(&HostP->Mapping[unit], sizeof(struct Map));
1188
1189 /* At this point under the right(wrong?) conditions
1190 ** we may have a first unit ID being higher than the
1191 ** second unit ID. This is a bad idea if we are about
1192 ** to fill the slots with a 16 port RTA.
1193 ** Better check and swap them over.
1194 */
1195
1196 if (*pID1 > *pID2)
1197 {
1198 rio_dprintk (RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2);
1199 tempID = *pID1;
1200 *pID1 = *pID2;
1201 *pID2 = tempID;
1202 }
1203 return 0;
1204 }
1205 }
1206 }
1207
1208 /*
1209 ** If we manage to get to the end of the second loop then we
1210 ** can give up and return a failure.
1211 */
1212 return 1;
1213}
1214
1215
1216/*
1217** The link switch scenario.
1218**
1219** Rta Wun (A) is connected to Tuw (A).
1220** The tables are all up to date, and the system is OK.
1221**
1222** If Wun (A) is now moved to Wun (B) before Wun (A) can
1223** become disconnected, then the follow happens:
1224**
1225** Tuw (A) spots the change of unit:link at the other end
1226** of its link and Tuw sends a topology packet reflecting
1227** the change: Tuw (A) now disconnected from Wun (A), and
1228** this is closely followed by a packet indicating that
1229** Tuw (A) is now connected to Wun (B).
1230**
1231** Wun (B) will spot that it has now become connected, and
1232** Wun will send a topology packet, which indicates that
1233** both Wun (A) and Wun (B) is connected to Tuw (A).
1234**
1235** Eventually Wun (A) realises that it is now disconnected
1236** and Wun will send out a topology packet indicating that
1237** Wun (A) is now disconnected.
1238*/
diff --git a/drivers/char/rio/riospace.h b/drivers/char/rio/riospace.h
new file mode 100644
index 000000000000..32b09b0f23aa
--- /dev/null
+++ b/drivers/char/rio/riospace.h
@@ -0,0 +1,161 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riospace.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:13
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)riospace.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_riospace_h__
34#define __rio_riospace_h__
35
36#ifdef SCCS_LABELS
37static char *_riospace_h_sccs_ = "@(#)riospace.h 1.2";
38#endif
39
40#define RIO_LOCATOR_LEN 16
41#define MAX_RIO_BOARDS 4
42
43/*
44** DONT change this file. At all. Unless you can rebuild the entire
45** device driver, which you probably can't, then the rest of the
46** driver won't see any changes you make here. So don't make any.
47** In particular, it won't be able to see changes to RIO_SLOTS
48*/
49
50struct Conf
51{
52 char Locator[24];
53 unsigned int StartupTime;
54 unsigned int SlowCook;
55 unsigned int IntrPollTime;
56 unsigned int BreakInterval;
57 unsigned int Timer;
58 unsigned int RtaLoadBase;
59 unsigned int HostLoadBase;
60 unsigned int XpHz;
61 unsigned int XpCps;
62 char *XpOn;
63 char *XpOff;
64 unsigned int MaxXpCps;
65 unsigned int MinXpCps;
66 unsigned int SpinCmds;
67 unsigned int FirstAddr;
68 unsigned int LastAddr;
69 unsigned int BufferSize;
70 unsigned int LowWater;
71 unsigned int LineLength;
72 unsigned int CmdTime;
73};
74
75/*
76** Board types - these MUST correspond to product codes!
77*/
78#define RIO_EMPTY 0x0
79#define RIO_EISA 0x3
80#define RIO_RTA_16 0x9
81#define RIO_AT 0xA
82#define RIO_MCA 0xB
83#define RIO_PCI 0xD
84#define RIO_RTA 0xE
85
86/*
87** Board data structure. This is used for configuration info
88*/
89struct Brd
90{
91 unsigned char Type; /* RIO_EISA, RIO_MCA, RIO_AT, RIO_EMPTY... */
92 unsigned char Ivec; /* POLLED or ivec number */
93 unsigned char Mode; /* Control stuff, see below */
94};
95
96struct Board
97{
98 char Locator[RIO_LOCATOR_LEN];
99 int NumSlots;
100 struct Brd Boards[MAX_RIO_BOARDS];
101};
102
103#define BOOT_FROM_LINK 0x00
104#define BOOT_FROM_RAM 0x01
105#define EXTERNAL_BUS_OFF 0x00
106#define EXTERNAL_BUS_ON 0x02
107#define INTERRUPT_DISABLE 0x00
108#define INTERRUPT_ENABLE 0x04
109#define BYTE_OPERATION 0x00
110#define WORD_OPERATION 0x08
111#define POLLED INTERRUPT_DISABLE
112#define IRQ_15 (0x00 | INTERRUPT_ENABLE)
113#define IRQ_12 (0x10 | INTERRUPT_ENABLE)
114#define IRQ_11 (0x20 | INTERRUPT_ENABLE)
115#define IRQ_9 (0x30 | INTERRUPT_ENABLE)
116#define SLOW_LINKS 0x00
117#define FAST_LINKS 0x40
118#define SLOW_AT_BUS 0x00
119#define FAST_AT_BUS 0x80
120#define SLOW_PCI_TP 0x00
121#define FAST_PCI_TP 0x80
122/*
123** Debug levels
124*/
125#define DBG_NONE 0x00000000
126
127#define DBG_INIT 0x00000001
128#define DBG_OPEN 0x00000002
129#define DBG_CLOSE 0x00000004
130#define DBG_IOCTL 0x00000008
131
132#define DBG_READ 0x00000010
133#define DBG_WRITE 0x00000020
134#define DBG_INTR 0x00000040
135#define DBG_PROC 0x00000080
136
137#define DBG_PARAM 0x00000100
138#define DBG_CMD 0x00000200
139#define DBG_XPRINT 0x00000400
140#define DBG_POLL 0x00000800
141
142#define DBG_DAEMON 0x00001000
143#define DBG_FAIL 0x00002000
144#define DBG_MODEM 0x00004000
145#define DBG_LIST 0x00008000
146
147#define DBG_ROUTE 0x00010000
148#define DBG_UTIL 0x00020000
149#define DBG_BOOT 0x00040000
150#define DBG_BUFFER 0x00080000
151
152#define DBG_MON 0x00100000
153#define DBG_SPECIAL 0x00200000
154#define DBG_VPIX 0x00400000
155#define DBG_FLUSH 0x00800000
156
157#define DBG_QENABLE 0x01000000
158
159#define DBG_ALWAYS 0x80000000
160
161#endif /* __rio_riospace_h__ */
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
new file mode 100644
index 000000000000..8fb26ad2aa12
--- /dev/null
+++ b/drivers/char/rio/riotable.c
@@ -0,0 +1,1044 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riotable.c
24** SID : 1.2
25** Last Modified : 11/6/98 10:33:47
26** Retrieved : 11/6/98 10:33:50
27**
28** ident @(#)riotable.c 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32#ifdef SCCS_LABELS
33static char *_riotable_c_sccs_ = "@(#)riotable.c 1.2";
34#endif
35
36#include <linux/module.h>
37#include <linux/slab.h>
38#include <linux/errno.h>
39#include <linux/interrupt.h>
40#include <linux/string.h>
41
42#include <asm/io.h>
43#include <asm/system.h>
44#include <asm/string.h>
45#include <asm/semaphore.h>
46#include <asm/uaccess.h>
47
48#include <linux/termios.h>
49#include <linux/serial.h>
50
51#include <linux/generic_serial.h>
52
53
54#include "linux_compat.h"
55#include "rio_linux.h"
56#include "typdef.h"
57#include "pkt.h"
58#include "daemon.h"
59#include "rio.h"
60#include "riospace.h"
61#include "top.h"
62#include "cmdpkt.h"
63#include "map.h"
64#include "riotypes.h"
65#include "rup.h"
66#include "port.h"
67#include "riodrvr.h"
68#include "rioinfo.h"
69#include "func.h"
70#include "errors.h"
71#include "pci.h"
72
73#include "parmmap.h"
74#include "unixrup.h"
75#include "board.h"
76#include "host.h"
77#include "error.h"
78#include "phb.h"
79#include "link.h"
80#include "cmdblk.h"
81#include "route.h"
82#include "control.h"
83#include "cirrus.h"
84#include "rioioctl.h"
85#include "param.h"
86#include "list.h"
87#include "sam.h"
88#include "protsts.h"
89
90/*
91** A configuration table has been loaded. It is now up to us
92** to sort it out and use the information contained therein.
93*/
94int
95RIONewTable(p)
96struct rio_info * p;
97{
98 int Host, Host1, Host2, NameIsUnique, Entry, SubEnt;
99 struct Map *MapP;
100 struct Map *HostMapP;
101 struct Host *HostP;
102
103 char *cptr;
104
105 /*
106 ** We have been sent a new table to install. We need to break
107 ** it down into little bits and spread it around a bit to see
108 ** what we have got.
109 */
110 /*
111 ** Things to check:
112 ** (things marked 'xx' aren't checked any more!)
113 ** (1) That there are no booted Hosts/RTAs out there.
114 ** (2) That the names are properly formed
115 ** (3) That blank entries really are.
116 ** xx (4) That hosts mentioned in the table actually exist. xx
117 ** (5) That the IDs are unique (per host).
118 ** (6) That host IDs are zero
119 ** (7) That port numbers are valid
120 ** (8) That port numbers aren't duplicated
121 ** (9) That names aren't duplicated
122 ** xx (10) That hosts that actually exist are mentioned in the table. xx
123 */
124 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n");
125 if ( p->RIOSystemUp ) { /* (1) */
126 p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED;
127 return -EBUSY;
128 }
129
130 p->RIOError.Error = NOTHING_WRONG_AT_ALL;
131 p->RIOError.Entry = -1;
132 p->RIOError.Other = -1;
133
134 for ( Entry=0; Entry<TOTAL_MAP_ENTRIES; Entry++ ) {
135 MapP = &p->RIOConnectTable[Entry];
136 if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) {
137 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n");
138 cptr = MapP->Name; /* (2) */
139 cptr[MAX_NAME_LEN-1]='\0';
140 if ( cptr[0]=='\0' ) {
141 bcopy(MapP->RtaUniqueNum?"RTA NN":"HOST NN",MapP->Name,8);
142 MapP->Name[5] = '0'+Entry/10;
143 MapP->Name[6] = '0'+Entry%10;
144 }
145 while ( *cptr ) {
146 if ( *cptr<' ' || *cptr>'~' ) {
147 p->RIOError.Error = BAD_CHARACTER_IN_NAME;
148 p->RIOError.Entry = Entry;
149 return -ENXIO;
150 }
151 cptr++;
152 }
153 }
154
155 /*
156 ** If the entry saved was a tentative entry then just forget
157 ** about it.
158 */
159 if ( MapP->Flags & SLOT_TENTATIVE ) {
160 MapP->HostUniqueNum = 0;
161 MapP->RtaUniqueNum = 0;
162 continue;
163 }
164
165 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n");
166 if ( !MapP->RtaUniqueNum && !MapP->HostUniqueNum ) { /* (3) */
167 if ( MapP->ID || MapP->SysPort || MapP->Flags ) {
168 rio_dprintk (RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n",MapP->Name);
169 p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL;
170 p->RIOError.Entry = Entry;
171 return -ENXIO;
172 }
173 rio_dprintk (RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n");
174 continue;
175 }
176
177 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n");
178 for ( Host=0; Host<p->RIONumHosts; Host++ ) { /* (4) */
179 if ( p->RIOHosts[Host].UniqueNum==MapP->HostUniqueNum ) {
180 HostP = &p->RIOHosts[Host];
181 /*
182 ** having done the lookup, we don't really want to do
183 ** it again, so hang the host number in a safe place
184 */
185 MapP->Topology[0].Unit = Host;
186 break;
187 }
188 }
189
190 if ( Host >= p->RIONumHosts ) {
191 rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n",
192 MapP->Name, MapP->HostUniqueNum);
193 MapP->HostUniqueNum = 0;
194 /* MapP->RtaUniqueNum = 0; */
195 /* MapP->ID = 0; */
196 /* MapP->Flags = 0; */
197 /* MapP->SysPort = 0; */
198 /* MapP->Name[0] = 0; */
199 continue;
200 }
201
202 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n");
203 if ( MapP->RtaUniqueNum ) { /* (5) */
204 if ( !MapP->ID ) {
205 rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n",
206 MapP->Name);
207 p->RIOError.Error = ZERO_RTA_ID;
208 p->RIOError.Entry = Entry;
209 return -ENXIO;
210 }
211 if ( MapP->ID > MAX_RUP ) {
212 rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n",
213 MapP->Name, MapP->ID);
214 p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
215 p->RIOError.Entry = Entry;
216 return -ENXIO;
217 }
218 for ( SubEnt=0; SubEnt<Entry; SubEnt++ ) {
219 if ( MapP->HostUniqueNum ==
220 p->RIOConnectTable[SubEnt].HostUniqueNum &&
221 MapP->ID == p->RIOConnectTable[SubEnt].ID ) {
222 rio_dprintk (RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n",
223 MapP->Name, p->RIOConnectTable[SubEnt].Name);
224 p->RIOError.Error = DUPLICATED_RTA_ID;
225 p->RIOError.Entry = Entry;
226 p->RIOError.Other = SubEnt;
227 return -ENXIO;
228 }
229 /*
230 ** If the RtaUniqueNum is the same, it may be looking at both
231 ** entries for a 16 port RTA, so check the ids
232 */
233 if ((MapP->RtaUniqueNum ==
234 p->RIOConnectTable[SubEnt].RtaUniqueNum)
235 && (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) {
236 rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",MapP->Name);
237 rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",
238 p->RIOConnectTable[SubEnt].Name);
239 p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER;
240 p->RIOError.Entry = Entry;
241 p->RIOError.Other = SubEnt;
242 return -ENXIO;
243 }
244 }
245 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n");
246 /* (7a) */
247 if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort % PORTS_PER_RTA)) {
248 rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n",
249 (int)MapP->SysPort,MapP->Name, PORTS_PER_RTA);
250 p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
251 p->RIOError.Entry = Entry;
252 return -ENXIO;
253 }
254 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n");
255 /* (7b) */
256 if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort >= RIO_PORTS)) {
257 rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n",
258 (int)MapP->SysPort, MapP->Name);
259 p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
260 p->RIOError.Entry = Entry;
261 return -ENXIO;
262 }
263 for ( SubEnt=0; SubEnt<Entry; SubEnt++ ) {
264 if ( p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT )
265 continue;
266 if ( p->RIOConnectTable[SubEnt].RtaUniqueNum ) {
267 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n");
268 /* (8) */
269 if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort ==
270 p->RIOConnectTable[SubEnt].SysPort) ) {
271 rio_dprintk (RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n",
272 MapP->Name, p->RIOConnectTable[SubEnt].Name,
273 (int)MapP->SysPort);
274 p->RIOError.Error = TTY_NUMBER_IN_USE;
275 p->RIOError.Entry = Entry;
276 p->RIOError.Other = SubEnt;
277 return -ENXIO;
278 }
279 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n");
280 if (strcmp(MapP->Name,
281 p->RIOConnectTable[SubEnt].Name)==0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */
282 rio_dprintk (RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
283 p->RIOError.Error = NAME_USED_TWICE;
284 p->RIOError.Entry = Entry;
285 p->RIOError.Other = SubEnt;
286 return -ENXIO;
287 }
288 }
289 }
290 }
291 else { /* (6) */
292 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n");
293 if ( MapP->ID ) {
294 rio_dprintk (RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n",
295 MapP->Name);
296 p->RIOError.Error = HOST_ID_NOT_ZERO;
297 p->RIOError.Entry = Entry;
298 return -ENXIO;
299 }
300 if ( MapP->SysPort != NO_PORT ) {
301 rio_dprintk (RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n",
302 MapP->Name);
303 p->RIOError.Error = HOST_SYSPORT_BAD;
304 p->RIOError.Entry = Entry;
305 return -ENXIO;
306 }
307 }
308 }
309
310 /*
311 ** wow! if we get here then it's a goody!
312 */
313
314 /*
315 ** Zero the (old) entries for each host...
316 */
317 for ( Host=0; Host<RIO_HOSTS; Host++ ) {
318 for ( Entry=0; Entry<MAX_RUP; Entry++ ) {
319 bzero((caddr_t)&p->RIOHosts[Host].Mapping[Entry],
320 sizeof(struct Map));
321 }
322 bzero((caddr_t)&p->RIOHosts[Host].Name[0],
323 sizeof(p->RIOHosts[Host].Name) );
324 }
325
326 /*
327 ** Copy in the new table entries
328 */
329 for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) {
330 rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry);
331 MapP = &p->RIOConnectTable[Entry];
332
333 /*
334 ** Now, if it is an empty slot ignore it!
335 */
336 if ( MapP->HostUniqueNum==0 )
337 continue;
338
339 /*
340 ** we saved the host number earlier, so grab it back
341 */
342 HostP = &p->RIOHosts[MapP->Topology[0].Unit];
343
344 /*
345 ** If it is a host, then we only need to fill in the name field.
346 */
347 if ( MapP->ID==0 ) {
348 rio_dprintk (RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name);
349 bcopy(MapP->Name,HostP->Name,MAX_NAME_LEN);
350 continue;
351 }
352
353 /*
354 ** Its an RTA entry, so fill in the host mapping entries for it
355 ** and the port mapping entries. Notice that entry zero is for
356 ** ID one.
357 */
358 HostMapP = &HostP->Mapping[MapP->ID-1];
359
360 if (MapP->Flags & SLOT_IN_USE) {
361 rio_dprintk (RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name);
362 /*
363 ** structure assign, then sort out the bits we shouldn't have done
364 */
365 *HostMapP = *MapP;
366
367 HostMapP->Flags = SLOT_IN_USE;
368 if (MapP->Flags & RTA16_SECOND_SLOT)
369 HostMapP->Flags |= RTA16_SECOND_SLOT;
370
371 RIOReMapPorts(p, HostP, HostMapP );
372 }
373 else {
374 rio_dprintk (RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name);
375 }
376 }
377
378 for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) {
379 p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry];
380 }
381
382 for ( Host=0; Host<p->RIONumHosts; Host++ ) {
383 for ( SubEnt=0; SubEnt<LINKS_PER_UNIT; SubEnt++ ) {
384 p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT;
385 p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK;
386 }
387 for ( Entry=0; Entry<MAX_RUP; Entry++ ) {
388 for ( SubEnt=0; SubEnt<LINKS_PER_UNIT; SubEnt++ ) {
389 p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit =
390 ROUTE_DISCONNECT;
391 p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link =
392 NO_LINK;
393 }
394 }
395 if ( !p->RIOHosts[Host].Name[0] ) {
396 bcopy("HOST 1",p->RIOHosts[Host].Name,7);
397 p->RIOHosts[Host].Name[5] += Host;
398 }
399 /*
400 ** Check that default name assigned is unique.
401 */
402 Host1 = Host;
403 NameIsUnique = 0;
404 while (!NameIsUnique) {
405 NameIsUnique = 1;
406 for ( Host2=0; Host2<p->RIONumHosts; Host2++ ) {
407 if (Host2 == Host)
408 continue;
409 if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name)
410 == 0) {
411 NameIsUnique = 0;
412 Host1++;
413 if (Host1 >= p->RIONumHosts)
414 Host1 = 0;
415 p->RIOHosts[Host].Name[5] = '1' + Host1;
416 }
417 }
418 }
419 /*
420 ** Rename host if name already used.
421 */
422 if (Host1 != Host)
423 {
424 rio_dprintk (RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name);
425 bcopy("HOST 1",p->RIOHosts[Host].Name,7);
426 p->RIOHosts[Host].Name[5] += Host1;
427 }
428 rio_dprintk (RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name);
429 }
430 return 0;
431}
432
433/*
434** User process needs the config table - build it from first
435** principles.
436*/
437int
438RIOApel(p)
439struct rio_info * p;
440{
441 int Host;
442 int link;
443 int Rup;
444 int Next = 0;
445 struct Map *MapP;
446 struct Host *HostP;
447 long oldspl;
448
449 disable(oldspl); /* strange but true! */
450
451 rio_dprintk (RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n");
452
453 bzero((caddr_t)&p->RIOConnectTable[0],
454 sizeof(struct Map) * TOTAL_MAP_ENTRIES );
455
456 for ( Host=0; Host<RIO_HOSTS; Host++ ) {
457 rio_dprintk (RIO_DEBUG_TABLE, "Processing host %d\n", Host);
458 HostP = &p->RIOHosts[Host];
459 MapP = &p->RIOConnectTable[Next++];
460 MapP->HostUniqueNum = HostP->UniqueNum;
461 if ( (HostP->Flags & RUN_STATE) != RC_RUNNING )
462 continue;
463 MapP->RtaUniqueNum = 0;
464 MapP->ID = 0;
465 MapP->Flags = SLOT_IN_USE;
466 MapP->SysPort = NO_PORT;
467 for ( link=0; link<LINKS_PER_UNIT; link++ )
468 MapP->Topology[link] = HostP->Topology[link];
469 bcopy(HostP->Name,MapP->Name,MAX_NAME_LEN);
470 for ( Rup=0; Rup<MAX_RUP; Rup++ ) {
471 if ( HostP->Mapping[Rup].Flags & (SLOT_IN_USE|SLOT_TENTATIVE) ) {
472 p->RIOConnectTable[Next] = HostP->Mapping[Rup];
473 if ( HostP->Mapping[Rup].Flags & SLOT_IN_USE)
474 p->RIOConnectTable[Next].Flags |= SLOT_IN_USE;
475 if ( HostP->Mapping[Rup].Flags & SLOT_TENTATIVE)
476 p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE;
477 if ( HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT )
478 p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT;
479 Next++;
480 }
481 }
482 }
483 restore(oldspl);
484 return 0;
485}
486
487/*
488** config.rio has taken a dislike to one of the gross maps entries.
489** if the entry is suitably inactive, then we can gob on it and remove
490** it from the table.
491*/
492int
493RIODeleteRta(p, MapP)
494struct rio_info *p;
495struct Map *MapP;
496{
497 int host, entry, port, link;
498 int SysPort;
499 struct Host *HostP;
500 struct Map *HostMapP;
501 struct Port *PortP;
502 int work_done = 0;
503 unsigned long lock_flags, sem_flags;
504
505 rio_dprintk (RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n",
506 MapP->HostUniqueNum, MapP->RtaUniqueNum);
507
508 for ( host=0; host < p->RIONumHosts; host++ ) {
509 HostP = &p->RIOHosts[host];
510
511 rio_spin_lock_irqsave( &HostP->HostLock, lock_flags );
512
513 if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
514 rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
515 continue;
516 }
517
518 for ( entry=0; entry<MAX_RUP; entry++ ) {
519 if ( MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum ) {
520 HostMapP = &HostP->Mapping[entry];
521 rio_dprintk (RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n",
522 entry, HostP->Name);
523
524 /*
525 ** Check all four links of the unit are disconnected
526 */
527 for ( link=0; link< LINKS_PER_UNIT; link++ ) {
528 if ( HostMapP->Topology[link].Unit != ROUTE_DISCONNECT ) {
529 rio_dprintk (RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n");
530 p->RIOError.Error = UNIT_IS_IN_USE;
531 rio_spin_unlock_irqrestore( &HostP->HostLock, lock_flags);
532 return -EBUSY;
533 }
534 }
535 /*
536 ** Slot has been allocated, BUT not booted/routed/
537 ** connected/selected or anything else-ed
538 */
539 SysPort = HostMapP->SysPort;
540
541 if ( SysPort != NO_PORT ) {
542 for (port=SysPort; port < SysPort+PORTS_PER_RTA; port++) {
543 PortP = p->RIOPortp[port];
544 rio_dprintk (RIO_DEBUG_TABLE, "Unmap port\n");
545
546 rio_spin_lock_irqsave( &PortP->portSem, sem_flags );
547
548 PortP->Mapped = 0;
549
550 if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) {
551
552 rio_dprintk (RIO_DEBUG_TABLE, "Gob on port\n");
553 PortP->TxBufferIn = PortP->TxBufferOut = 0;
554 /* What should I do
555 wakeup( &PortP->TxBufferIn );
556 wakeup( &PortP->TxBufferOut);
557 */
558 PortP->InUse = NOT_INUSE;
559 /* What should I do
560 wakeup( &PortP->InUse );
561 signal(PortP->TtyP->t_pgrp,SIGKILL);
562 ttyflush(PortP->TtyP,(FREAD|FWRITE));
563 */
564 PortP->State |= RIO_CLOSING | RIO_DELETED;
565 }
566
567 /*
568 ** For the second slot of a 16 port RTA, the
569 ** driver needs to reset the changes made to
570 ** the phb to port mappings in RIORouteRup.
571 */
572 if (PortP->SecondBlock) {
573 ushort dest_unit = HostMapP->ID;
574 ushort dest_port = port - SysPort;
575 WORD *TxPktP;
576 PKT *Pkt;
577
578 for (TxPktP = PortP->TxStart;
579 TxPktP <= PortP->TxEnd; TxPktP++) {
580 /*
581 ** *TxPktP is the pointer to the
582 ** transmit packet on the host card.
583 ** This needs to be translated into
584 ** a 32 bit pointer so it can be
585 ** accessed from the driver.
586 */
587 Pkt = (PKT *) RIO_PTR(HostP->Caddr,
588 RWORD(*TxPktP));
589 rio_dprintk (RIO_DEBUG_TABLE,
590 "Tx packet (%x) destination: Old %x:%x New %x:%x\n",
591 *TxPktP, Pkt->dest_unit,
592 Pkt->dest_port, dest_unit, dest_port);
593 WWORD(Pkt->dest_unit, dest_unit);
594 WWORD(Pkt->dest_port, dest_port);
595 }
596 rio_dprintk (RIO_DEBUG_TABLE,
597 "Port %d phb destination: Old %x:%x New %x:%x\n",
598 port, PortP->PhbP->destination & 0xff,
599 (PortP->PhbP->destination >> 8) & 0xff,
600 dest_unit, dest_port);
601 WWORD(PortP->PhbP->destination,
602 dest_unit + (dest_port << 8));
603 }
604 rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags);
605 }
606 }
607 rio_dprintk (RIO_DEBUG_TABLE, "Entry nulled.\n");
608 bzero((char *)HostMapP,sizeof(struct Map));
609 work_done++;
610 }
611 }
612 rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
613 }
614
615 /* XXXXX lock me up */
616 for ( entry=0; entry< TOTAL_MAP_ENTRIES; entry++ ) {
617 if ( p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum ) {
618 bzero((char *)&p->RIOSavedTable[entry],sizeof(struct Map));
619 work_done++;
620 }
621 if ( p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum ) {
622 bzero((char *)&p->RIOConnectTable[entry],sizeof(struct Map));
623 work_done++;
624 }
625 }
626 if ( work_done )
627 return 0;
628
629 rio_dprintk (RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n");
630 p->RIOError.Error = COULDNT_FIND_ENTRY;
631 return -ENXIO;
632}
633
634int RIOAssignRta( struct rio_info *p, struct Map *MapP )
635{
636 int host;
637 struct Map *HostMapP;
638 char *sptr;
639 int link;
640
641
642 rio_dprintk (RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
643 MapP->HostUniqueNum,MapP->RtaUniqueNum,
644 MapP->ID, (int)MapP->SysPort);
645
646 if ((MapP->ID != (ushort)-1) &&
647 ((int)MapP->ID < (int)1 || (int)MapP->ID > MAX_RUP ))
648 {
649 rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
650 p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
651 return -EINVAL;
652 }
653 if (MapP->RtaUniqueNum == 0)
654 {
655 rio_dprintk (RIO_DEBUG_TABLE, "Rta Unique number zero!\n");
656 p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO;
657 return -EINVAL;
658 }
659 if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA) )
660 {
661 rio_dprintk (RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA);
662 p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
663 return -EINVAL;
664 }
665 if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS) )
666 {
667 rio_dprintk (RIO_DEBUG_TABLE, "Port %d not valid!\n",(int)MapP->SysPort);
668 p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
669 return -EINVAL;
670 }
671
672 /*
673 ** Copy the name across to the map entry.
674 */
675 MapP->Name[MAX_NAME_LEN-1] = '\0';
676 sptr = MapP->Name;
677 while ( *sptr )
678 {
679 if ( *sptr<' ' || *sptr>'~' )
680 {
681 rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
682 p->RIOError.Error = BAD_CHARACTER_IN_NAME;
683 return -EINVAL;
684 }
685 sptr++;
686 }
687
688 for ( host=0; host < p->RIONumHosts; host++ )
689 {
690 if ( MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum )
691 {
692 if ( (p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING )
693 {
694 p->RIOError.Error = HOST_NOT_RUNNING;
695 return -ENXIO;
696 }
697
698 /*
699 ** Now we have a host we need to allocate an ID
700 ** if the entry does not already have one.
701 */
702 if (MapP->ID == (ushort)-1)
703 {
704 int nNewID;
705
706 rio_dprintk (RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n",
707 MapP->Name);
708 /*
709 ** The idea here is to allow RTA's to be assigned
710 ** before they actually appear on the network.
711 ** This allows the addition of RTA's without having
712 ** to plug them in.
713 ** What we do is:
714 ** - Find a free ID and allocate it to the RTA.
715 ** - If this map entry is the second half of a
716 ** 16 port entry then find the other half and
717 ** make sure the 2 cross reference each other.
718 */
719 if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0)
720 {
721 p->RIOError.Error = COULDNT_FIND_ENTRY;
722 return -EBUSY;
723 }
724 MapP->ID = (ushort)nNewID + 1;
725 rio_dprintk (RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID);
726 HostMapP = &p->RIOHosts[host].Mapping[nNewID];
727 HostMapP->RtaUniqueNum = MapP->RtaUniqueNum;
728 HostMapP->HostUniqueNum = MapP->HostUniqueNum;
729 HostMapP->ID = MapP->ID;
730 for (link = 0; link < LINKS_PER_UNIT; link++)
731 {
732 HostMapP->Topology[link].Unit = ROUTE_DISCONNECT;
733 HostMapP->Topology[link].Link = NO_LINK;
734 }
735 if (MapP->Flags & RTA16_SECOND_SLOT)
736 {
737 int unit;
738
739 for (unit = 0; unit < MAX_RUP; unit++)
740 if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum ==
741 MapP->RtaUniqueNum)
742 break;
743 if (unit == MAX_RUP)
744 {
745 p->RIOError.Error = COULDNT_FIND_ENTRY;
746 return -EBUSY;
747 }
748 HostMapP->Flags |= RTA16_SECOND_SLOT;
749 HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID;
750 p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID;
751 rio_dprintk (RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n",
752 MapP->ID,
753 p->RIOHosts[host].Mapping[unit].ID);
754 }
755 }
756
757 HostMapP = &p->RIOHosts[host].Mapping[MapP->ID-1];
758
759 if ( HostMapP->Flags & SLOT_IN_USE )
760 {
761 rio_dprintk (RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID);
762 p->RIOError.Error = ID_ALREADY_IN_USE;
763 return -EBUSY;
764 }
765
766 /*
767 ** Assign the sys ports and the name, and mark the slot as
768 ** being in use.
769 */
770 HostMapP->SysPort = MapP->SysPort;
771 if ((MapP->Flags & RTA16_SECOND_SLOT) == 0)
772 CCOPY( MapP->Name, HostMapP->Name, MAX_NAME_LEN );
773 HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED;
774#if NEED_TO_FIX
775 RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID-1]);
776#endif
777 if (MapP->Flags & RTA16_SECOND_SLOT)
778 HostMapP->Flags |= RTA16_SECOND_SLOT;
779
780 RIOReMapPorts( p, &p->RIOHosts[host], HostMapP );
781 /*
782 ** Adjust 2nd block of 8 phbs
783 */
784 if (MapP->Flags & RTA16_SECOND_SLOT)
785 RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1);
786
787 if ( HostMapP->SysPort != NO_PORT )
788 {
789 if ( HostMapP->SysPort < p->RIOFirstPortsBooted )
790 p->RIOFirstPortsBooted = HostMapP->SysPort;
791 if ( HostMapP->SysPort > p->RIOLastPortsBooted )
792 p->RIOLastPortsBooted = HostMapP->SysPort;
793 }
794 if (MapP->Flags & RTA16_SECOND_SLOT)
795 rio_dprintk (RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n",
796 p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name);
797 else
798 rio_dprintk (RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name);
799 return 0;
800 }
801 }
802 p->RIOError.Error = UNKNOWN_HOST_NUMBER;
803 rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
804 return -ENXIO;
805}
806
807
808int
809RIOReMapPorts(p, HostP, HostMapP)
810struct rio_info * p;
811struct Host *HostP;
812struct Map *HostMapP;
813{
814 register struct Port *PortP;
815 uint SubEnt;
816 uint HostPort;
817 uint SysPort;
818 ushort RtaType;
819 unsigned long flags;
820
821#ifdef CHECK
822 CheckHostP( HostP );
823 CheckHostMapP( HostMapP );
824#endif
825
826 rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int)HostMapP->SysPort, HostMapP->ID);
827
828 /*
829 ** We need to tell the UnixRups which sysport the rup corresponds to
830 */
831 HostP->UnixRups[HostMapP->ID-1].BaseSysPort = HostMapP->SysPort;
832
833 if ( HostMapP->SysPort == NO_PORT )
834 return(0);
835
836 RtaType = GetUnitType(HostMapP->RtaUniqueNum);
837 rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n",
838 (int)HostMapP->SysPort, (int)HostMapP->SysPort+PORTS_PER_RTA-1);
839
840 /*
841 ** now map each of its eight ports
842 */
843 for ( SubEnt=0; SubEnt<PORTS_PER_RTA; SubEnt++) {
844 rio_dprintk (RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n",
845 SubEnt, (int)HostMapP->SysPort);
846 SysPort = HostMapP->SysPort+SubEnt; /* portnumber within system */
847 /* portnumber on host */
848
849 HostPort = (HostMapP->ID-1)*PORTS_PER_RTA+SubEnt;
850
851 rio_dprintk (RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp);
852 PortP = p->RIOPortp[SysPort];
853#if 0
854 PortP->TtyP = &p->channel[SysPort];
855#endif
856 rio_dprintk (RIO_DEBUG_TABLE, "Map port\n");
857
858 /*
859 ** Point at all the real neat data structures
860 */
861 rio_spin_lock_irqsave(&PortP->portSem, flags);
862 PortP->HostP = HostP;
863 PortP->Caddr = HostP->Caddr;
864
865 /*
866 ** The PhbP cannot be filled in yet
867 ** unless the host has been booted
868 */
869 if ((HostP->Flags & RUN_STATE) == RC_RUNNING) {
870 struct PHB *PhbP = PortP->PhbP = &HostP->PhbP[HostPort];
871 PortP->TxAdd =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->tx_add));
872 PortP->TxStart =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->tx_start));
873 PortP->TxEnd =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->tx_end));
874 PortP->RxRemove=(WORD *)RIO_PTR(HostP->Caddr,
875 RWORD(PhbP->rx_remove));
876 PortP->RxStart =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->rx_start));
877 PortP->RxEnd =(WORD *)RIO_PTR(HostP->Caddr,RWORD(PhbP->rx_end));
878 }
879 else
880 PortP->PhbP = NULL;
881
882 /*
883 ** port related flags
884 */
885 PortP->HostPort = HostPort;
886 /*
887 ** For each part of a 16 port RTA, RupNum is ID - 1.
888 */
889 PortP->RupNum = HostMapP->ID - 1;
890 if (HostMapP->Flags & RTA16_SECOND_SLOT) {
891 PortP->ID2 = HostMapP->ID2 - 1;
892 PortP->SecondBlock = TRUE;
893 }
894 else {
895 PortP->ID2 = 0;
896 PortP->SecondBlock = FALSE;
897 }
898 PortP->RtaUniqueNum = HostMapP->RtaUniqueNum;
899
900 /*
901 ** If the port was already mapped then thats all we need to do.
902 */
903 if (PortP->Mapped) {
904 rio_spin_unlock_irqrestore( &PortP->portSem, flags);
905 continue;
906 }
907 else HostMapP->Flags &= ~RTA_NEWBOOT;
908
909 PortP->State = 0;
910 PortP->Config = 0;
911 /*
912 ** Check out the module type - if it is special (read only etc.)
913 ** then we need to set flags in the PortP->Config.
914 ** Note: For 16 port RTA, all ports are of the same type.
915 */
916 if (RtaType == TYPE_RTA16) {
917 PortP->Config |= p->RIOModuleTypes[HostP->UnixRups
918 [HostMapP->ID-1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE];
919 } else {
920 if ( SubEnt < PORTS_PER_MODULE )
921 PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups
922 [HostMapP->ID-1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
923 else
924 PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups
925 [HostMapP->ID-1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
926 }
927
928 /*
929 ** more port related flags
930 */
931 PortP->PortState = 0;
932 PortP->ModemLines = 0;
933 PortP->ModemState = 0;
934 PortP->CookMode = COOK_WELL;
935 PortP->ParamSem = 0;
936 PortP->FlushCmdBodge= 0;
937 PortP->WflushFlag = 0;
938 PortP->MagicFlags = 0;
939 PortP->Lock = 0;
940 PortP->Store = 0;
941 PortP->FirstOpen = 1;
942
943 /*
944 ** Buffers 'n things
945 */
946 PortP->RxDataStart = 0;
947 PortP->Cor2Copy = 0;
948 PortP->Name = &HostMapP->Name[0];
949#ifdef STATS
950 bzero( (caddr_t)&PortP->Stat, sizeof(struct RIOStats) );
951#endif
952 PortP->statsGather = 0;
953 PortP->txchars = 0;
954 PortP->rxchars = 0;
955 PortP->opens = 0;
956 PortP->closes = 0;
957 PortP->ioctls = 0;
958 if ( PortP->TxRingBuffer )
959 bzero( PortP->TxRingBuffer, p->RIOBufferSize );
960 else if ( p->RIOBufferSize ) {
961 PortP->TxRingBuffer = sysbrk(p->RIOBufferSize);
962 bzero( PortP->TxRingBuffer, p->RIOBufferSize );
963 }
964 PortP->TxBufferOut = 0;
965 PortP->TxBufferIn = 0;
966 PortP->Debug = 0;
967 /*
968 ** LastRxTgl stores the state of the rx toggle bit for this
969 ** port, to be compared with the state of the next pkt received.
970 ** If the same, we have received the same rx pkt from the RTA
971 ** twice. Initialise to a value not equal to PHB_RX_TGL or 0.
972 */
973 PortP->LastRxTgl = ~(uchar)PHB_RX_TGL;
974
975 /*
976 ** and mark the port as usable
977 */
978 PortP->Mapped = 1;
979 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
980 }
981 if ( HostMapP->SysPort < p->RIOFirstPortsMapped )
982 p->RIOFirstPortsMapped = HostMapP->SysPort;
983 if ( HostMapP->SysPort > p->RIOLastPortsMapped )
984 p->RIOLastPortsMapped = HostMapP->SysPort;
985
986 return 0;
987}
988
989int
990RIOChangeName(p, MapP)
991struct rio_info *p;
992struct Map* MapP;
993{
994 int host;
995 struct Map *HostMapP;
996 char *sptr;
997
998 rio_dprintk (RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
999 MapP->HostUniqueNum,MapP->RtaUniqueNum,
1000 MapP->ID, (int)MapP->SysPort);
1001
1002 if ( MapP->ID > MAX_RUP ) {
1003 rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
1004 p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
1005 return -EINVAL;
1006 }
1007
1008 MapP->Name[MAX_NAME_LEN-1] = '\0';
1009 sptr = MapP->Name;
1010
1011 while ( *sptr ) {
1012 if ( *sptr<' ' || *sptr>'~' ) {
1013 rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
1014 p->RIOError.Error = BAD_CHARACTER_IN_NAME;
1015 return -EINVAL;
1016 }
1017 sptr++;
1018 }
1019
1020 for ( host=0; host < p->RIONumHosts; host++ ) {
1021 if ( MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum ) {
1022 if ( (p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING ) {
1023 p->RIOError.Error = HOST_NOT_RUNNING;
1024 return -ENXIO;
1025 }
1026 if ( MapP->ID==0 ) {
1027 CCOPY( MapP->Name, p->RIOHosts[host].Name, MAX_NAME_LEN );
1028 return 0;
1029 }
1030
1031 HostMapP = &p->RIOHosts[host].Mapping[MapP->ID-1];
1032
1033 if ( HostMapP->RtaUniqueNum != MapP->RtaUniqueNum ) {
1034 p->RIOError.Error = RTA_NUMBER_WRONG;
1035 return -ENXIO;
1036 }
1037 CCOPY( MapP->Name, HostMapP->Name, MAX_NAME_LEN );
1038 return 0;
1039 }
1040 }
1041 p->RIOError.Error = UNKNOWN_HOST_NUMBER;
1042 rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
1043 return -ENXIO;
1044}
diff --git a/drivers/char/rio/riotime.h b/drivers/char/rio/riotime.h
new file mode 100644
index 000000000000..66d52bc0549b
--- /dev/null
+++ b/drivers/char/rio/riotime.h
@@ -0,0 +1,63 @@
1/****************************************************************************
2 ******* *******
3 ******* T I M E
4 ******* *******
5 ****************************************************************************
6
7 Author : Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
12 *
13
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 Version : 0.01
29
30
31 Mods
32 ----------------------------------------------------------------------------
33 Date By Description
34 ----------------------------------------------------------------------------
35
36 ***************************************************************************/
37
38#ifndef _riotime_h
39#define _riotime_h 1
40
41#ifndef lint
42#ifdef SCCS
43static char *_rio_riotime_h_sccs = "@(#)riotime.h 1.1" ;
44#endif
45#endif
46
47#define TWO_POWER_FIFTEEN (ushort)32768
48#define RioTime() riotime
49#define RioTimeAfter(time1,time2) ((ushort)time1 - (ushort)time2) < TWO_POWER_FIFTEEN
50#define RioTimePlus(time1,time2) ((ushort)time1 + (ushort)time2)
51
52/**************************************
53 * Convert a RIO tick (1/10th second)
54 * into transputer low priority ticks
55 *************************************/
56#define RioTimeToLow(time) (time*(100000 / 64))
57#define RioLowToTime(time) ((time*64)/100000)
58
59#define RIOTENTHSECOND (ushort)1
60#define RIOSECOND (ushort)(RIOTENTHSECOND * 10)
61#endif
62
63/*********** end of file ***********/
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
new file mode 100644
index 000000000000..db655002671f
--- /dev/null
+++ b/drivers/char/rio/riotty.c
@@ -0,0 +1,1376 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riotty.c
24** SID : 1.3
25** Last Modified : 11/6/98 10:33:47
26** Retrieved : 11/6/98 10:33:50
27**
28** ident @(#)riotty.c 1.3
29**
30** -----------------------------------------------------------------------------
31*/
32#ifdef SCCS_LABELS
33static char *_riotty_c_sccs_ = "@(#)riotty.c 1.3";
34#endif
35
36
37#define __EXPLICIT_DEF_H__
38
39#include <linux/module.h>
40#include <linux/slab.h>
41#include <linux/errno.h>
42#include <linux/tty.h>
43#include <linux/string.h>
44#include <asm/io.h>
45#include <asm/system.h>
46#include <asm/string.h>
47#include <asm/semaphore.h>
48#include <asm/uaccess.h>
49
50#include <linux/termios.h>
51
52#include <linux/serial.h>
53
54#include <linux/generic_serial.h>
55
56
57#include "linux_compat.h"
58#include "rio_linux.h"
59#include "typdef.h"
60#include "pkt.h"
61#include "daemon.h"
62#include "rio.h"
63#include "riospace.h"
64#include "top.h"
65#include "cmdpkt.h"
66#include "map.h"
67#include "riotypes.h"
68#include "rup.h"
69#include "port.h"
70#include "riodrvr.h"
71#include "rioinfo.h"
72#include "func.h"
73#include "errors.h"
74#include "pci.h"
75
76#include "parmmap.h"
77#include "unixrup.h"
78#include "board.h"
79#include "host.h"
80#include "error.h"
81#include "phb.h"
82#include "link.h"
83#include "cmdblk.h"
84#include "route.h"
85#include "control.h"
86#include "cirrus.h"
87#include "rioioctl.h"
88#include "param.h"
89#include "list.h"
90#include "sam.h"
91
92#if 0
93static void ttyseth_pv(struct Port *, struct ttystatics *,
94 struct termios *sg, int);
95#endif
96
97static void RIOClearUp(struct Port *PortP);
98int RIOShortCommand(struct rio_info *p, struct Port *PortP,
99 int command, int len, int arg);
100
101#if 0
102static int RIOCookMode(struct ttystatics *);
103#endif
104
105extern int conv_vb[]; /* now defined in ttymgr.c */
106extern int conv_bv[]; /* now defined in ttymgr.c */
107
108/*
109** 16.09.1998 ARG - Fix to build riotty.k.o for Modular Kernel Support
110**
111** ep.def.h is necessary for Modular Kernel Support
112** DO NOT place any kernel 'extern's after this line
113** or this source file will not build riotty.k.o
114*/
115#ifdef uLYNX
116#include <ep.def.h>
117#endif
118
119#ifdef NEED_THIS2
120static struct old_sgttyb
121default_sg =
122{
123 B19200, B19200, /* input and output speed */
124 'H' - '@', /* erase char */
125 -1, /* 2nd erase char */
126 'U' - '@', /* kill char */
127 ECHO | CRMOD, /* mode */
128 'C' - '@', /* interrupt character */
129 '\\' - '@', /* quit char */
130 'Q' - '@', /* start char */
131 'S' - '@', /* stop char */
132 'D' - '@', /* EOF */
133 -1, /* brk */
134 (LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */
135 'Z' - '@', /* process stop */
136 'Y' - '@', /* delayed stop */
137 'R' - '@', /* reprint line */
138 'O' - '@', /* flush output */
139 'W' - '@', /* word erase */
140 'V' - '@' /* literal next char */
141};
142#endif
143
144
145extern struct rio_info *p;
146
147
148int
149riotopen(struct tty_struct * tty, struct file * filp)
150{
151 register uint SysPort;
152 int Modem;
153 int repeat_this = 250;
154 struct Port *PortP; /* pointer to the port structure */
155 unsigned long flags;
156 int retval = 0;
157
158 func_enter ();
159
160 /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
161 is going to oops.
162 */
163 tty->driver_data = NULL;
164
165 SysPort = rio_minor(tty);
166 Modem = rio_ismodem(tty);
167
168 if ( p->RIOFailed ) {
169 rio_dprintk (RIO_DEBUG_TTY, "System initialisation failed\n");
170 pseterr(ENXIO);
171 func_exit ();
172 return -ENXIO;
173 }
174
175 rio_dprintk (RIO_DEBUG_TTY, "port open SysPort %d (%s) (mapped:%d)\n",
176 SysPort, Modem ? "Modem" : "tty",
177 p->RIOPortp[SysPort]->Mapped);
178
179 /*
180 ** Validate that we have received a legitimate request.
181 ** Currently, just check that we are opening a port on
182 ** a host card that actually exists, and that the port
183 ** has been mapped onto a host.
184 */
185 if (SysPort >= RIO_PORTS) { /* out of range ? */
186 rio_dprintk (RIO_DEBUG_TTY, "Illegal port number %d\n",SysPort);
187 pseterr(ENXIO);
188 func_exit();
189 return -ENXIO;
190 }
191
192 /*
193 ** Grab pointer to the port stucture
194 */
195 PortP = p->RIOPortp[SysPort]; /* Get control struc */
196 rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP);
197 if ( !PortP->Mapped ) { /* we aren't mapped yet! */
198 /*
199 ** The system doesn't know which RTA this port
200 ** corresponds to.
201 */
202 rio_dprintk (RIO_DEBUG_TTY, "port not mapped into system\n");
203 func_exit ();
204 pseterr(ENXIO);
205 return -ENXIO;
206 }
207
208 tty->driver_data = PortP;
209
210 PortP->gs.tty = tty;
211 PortP->gs.count++;
212
213 rio_dprintk (RIO_DEBUG_TTY, "%d bytes in tx buffer\n",
214 PortP->gs.xmit_cnt);
215
216 retval = gs_init_port (&PortP->gs);
217 if (retval) {
218 PortP->gs.count--;
219 return -ENXIO;
220 }
221 /*
222 ** If the host hasn't been booted yet, then
223 ** fail
224 */
225 if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
226 rio_dprintk (RIO_DEBUG_TTY, "Host not running\n");
227 pseterr(ENXIO);
228 func_exit ();
229 return -ENXIO;
230 }
231
232 /*
233 ** If the RTA has not booted yet and the user has choosen to block
234 ** until the RTA is present then we must spin here waiting for
235 ** the RTA to boot.
236 */
237#if 0
238 if (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
239 if (PortP->WaitUntilBooted) {
240 rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot\n");
241 do {
242 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
243 rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
244 func_exit ();
245 return -EINTR;
246 }
247 if (repeat_this -- <= 0) {
248 rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
249 RIOPreemptiveCmd(p, PortP, FCLOSE );
250 pseterr(EINTR);
251 func_exit ();
252 return -EIO;
253 }
254 } while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
255 rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
256 } else {
257 rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
258 pseterr(ENXIO);
259 func_exit ();
260 return 0;
261 }
262 }
263#else
264 /* I find the above code a bit hairy. I find the below code
265 easier to read and shorter. Now, if it works too that would
266 be great... -- REW
267 */
268 rio_dprintk (RIO_DEBUG_TTY, "Checking if RTA has booted... \n");
269 while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
270 if (!PortP->WaitUntilBooted) {
271 rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
272 func_exit ();
273 return -ENXIO;
274 }
275
276 /* Under Linux you'd normally use a wait instead of this
277 busy-waiting. I'll stick with the old implementation for
278 now. --REW
279 */
280 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
281 rio_dprintk (RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");
282 func_exit ();
283 return -EINTR;
284 }
285 if (repeat_this -- <= 0) {
286 rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
287 func_exit ();
288 return -EIO;
289 }
290 }
291 rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
292#endif
293#if 0
294 tp = PortP->TtyP; /* get tty struct */
295#endif
296 rio_spin_lock_irqsave(&PortP->portSem, flags);
297 if ( p->RIOHalted ) {
298 goto bombout;
299 }
300#if 0
301 retval = gs_init_port(&PortP->gs);
302 if (retval){
303 func_exit ();
304 return retval;
305 }
306#endif
307
308 /*
309 ** If the port is in the final throws of being closed,
310 ** we should wait here (politely), waiting
311 ** for it to finish, so that it doesn't close us!
312 */
313 while ( (PortP->State & RIO_CLOSING) && !p->RIOHalted ) {
314 rio_dprintk (RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
315 if (repeat_this -- <= 0) {
316 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
317 RIOPreemptiveCmd(p, PortP, FCLOSE );
318 retval = -EINTR;
319 goto bombout;
320 }
321 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
322 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
323 rio_spin_lock_irqsave(&PortP->portSem, flags);
324 retval = -EINTR;
325 goto bombout;
326 }
327 rio_spin_lock_irqsave(&PortP->portSem, flags);
328 }
329
330 if ( !PortP->Mapped ) {
331 rio_dprintk (RIO_DEBUG_TTY, "Port unmapped while closing!\n");
332 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
333 retval = -ENXIO;
334 func_exit ();
335 return retval;
336 }
337
338 if ( p->RIOHalted ) {
339 goto bombout;
340 }
341
342/*
343** 15.10.1998 ARG - ESIL 0761 part fix
344** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,
345** we need to make sure that the flags are clear when the port is opened.
346*/
347 /* Uh? Suppose I turn these on and then another process opens
348 the port again? The flags get cleared! Not good. -- REW */
349 if ( !(PortP->State & (RIO_LOPEN | RIO_MOPEN)) ) {
350 PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
351 }
352
353 if (!(PortP->firstOpen)) { /* First time ? */
354 rio_dprintk (RIO_DEBUG_TTY, "First open for this port\n");
355
356
357 PortP->firstOpen++;
358 PortP->CookMode = 0; /* XXX RIOCookMode(tp); */
359 PortP->InUse = NOT_INUSE;
360
361 /* Tentative fix for bug PR27. Didn't work. */
362 /* PortP->gs.xmit_cnt = 0; */
363
364 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
365#ifdef NEED_THIS
366 ttyseth(PortP, tp, (struct old_sgttyb *)&default_sg);
367#endif
368
369 /* Someone explain to me why this delay/config is
370 here. If I read the docs correctly the "open"
371 command piggybacks the parameters immediately.
372 -- REW */
373 RIOParam(PortP,OPEN,Modem,OK_TO_SLEEP); /* Open the port */
374#if 0
375 /* This delay of 1 second was annoying. I removed it. -- REW */
376 RIODelay(PortP, HUNDRED_MS*10);
377 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP); /* Config the port */
378#endif
379 rio_spin_lock_irqsave(&PortP->portSem, flags);
380
381 /*
382 ** wait for the port to be not closed.
383 */
384 while ( !(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted ) {
385 rio_dprintk (RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState);
386/*
387** 15.10.1998 ARG - ESIL 0759
388** (Part) fix for port being trashed when opened whilst RTA "disconnected"
389** Take out the limited wait - now wait for ever or until user
390** bangs us out.
391**
392 if (repeat_this -- <= 0) {
393 rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish timed out.\n"));
394 RIOPreemptiveCmd(p, PortP, FCLOSE );
395 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
396 return -EINTR;
397 }
398**
399*/
400 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
401 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
402 rio_dprintk (RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
403 RIOPreemptiveCmd(p, PortP, FCLOSE );
404 func_exit ();
405 return -EINTR;
406 }
407 rio_spin_lock_irqsave(&PortP->portSem, flags);
408 }
409
410 if ( p->RIOHalted ) {
411 retval = -EIO;
412bombout:
413 /* RIOClearUp( PortP ); */
414 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
415 return retval;
416 }
417 rio_dprintk (RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
418 }
419
420#ifdef MODEM_SUPPORT
421 if (Modem) {
422 rio_dprintk (RIO_DEBUG_TTY, "Modem - test for carrier\n");
423 /*
424 ** ACTION
425 ** insert test for carrier here. -- ???
426 ** I already see that test here. What's the deal? -- REW
427 */
428 if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
429 {
430 rio_dprintk (RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
431 /*
432 tp->tm.c_state |= CARR_ON;
433 wakeup((caddr_t) &tp->tm.c_canq);
434 */
435 PortP->State |= RIO_CARR_ON;
436 wake_up_interruptible (&PortP->gs.open_wait);
437 }
438 else /* no carrier - wait for DCD */
439 {
440 /*
441 while (!(PortP->gs.tty->termios->c_state & CARR_ON) &&
442 !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
443 */
444 while (!(PortP->State & RIO_CARR_ON) &&
445 !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) {
446
447 rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n",SysPort);
448 /*
449 PortP->gs.tty->termios->c_state |= WOPEN;
450 */
451 PortP->State |= RIO_WOPEN;
452 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
453 if (RIODelay (PortP, HUNDRED_MS) == RIO_FAIL)
454#if 0
455 if ( sleep((caddr_t)&tp->tm.c_canqo, TTIPRI|PCATCH))
456#endif
457 {
458 /*
459 ** ACTION: verify that this is a good thing
460 ** to do here. -- ???
461 ** I think it's OK. -- REW
462 */
463 rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n",
464 SysPort);
465 RIOPreemptiveCmd( p, PortP, FCLOSE );
466 /*
467 tp->tm.c_state &= ~WOPEN;
468 */
469 PortP->State &= ~RIO_WOPEN;
470 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
471 func_exit ();
472 return -EINTR;
473 }
474 }
475 PortP->State &= ~RIO_WOPEN;
476 }
477 if ( p->RIOHalted )
478 goto bombout;
479 rio_dprintk (RIO_DEBUG_TTY, "Setting RIO_MOPEN\n");
480 PortP->State |= RIO_MOPEN;
481 }
482 else
483#endif
484 {
485 /*
486 ** ACTION
487 ** Direct line open - force carrier (will probably mean
488 ** that sleeping Modem line fubar)
489 */
490 PortP->State |= RIO_LOPEN;
491 }
492
493 if ( p->RIOHalted ) {
494 goto bombout;
495 }
496
497 rio_dprintk (RIO_DEBUG_TTY, "high level open done\n");
498
499#ifdef STATS
500 PortP->Stat.OpenCnt++;
501#endif
502 /*
503 ** Count opens for port statistics reporting
504 */
505 if (PortP->statsGather)
506 PortP->opens++;
507
508 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
509 rio_dprintk (RIO_DEBUG_TTY, "Returning from open\n");
510 func_exit ();
511 return 0;
512}
513
514/*
515** RIOClose the port.
516** The operating system thinks that this is last close for the device.
517** As there are two interfaces to the port (Modem and tty), we need to
518** check that both are closed before we close the device.
519*/
520int
521riotclose(void *ptr)
522{
523#if 0
524 register uint SysPort = dev;
525 struct ttystatics *tp; /* pointer to our ttystruct */
526#endif
527 struct Port *PortP =ptr; /* pointer to the port structure */
528 int deleted = 0;
529 int try = -1; /* Disable the timeouts by setting them to -1 */
530 int repeat_this = -1; /* Congrats to those having 15 years of
531 uptime! (You get to break the driver.) */
532 long end_time;
533 struct tty_struct * tty;
534 unsigned long flags;
535 int Modem;
536 int rv =0;
537
538 rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
539
540 /* PortP = p->RIOPortp[SysPort]; */
541 rio_dprintk (RIO_DEBUG_TTY, "Port is at address 0x%x\n",(int)PortP);
542 /* tp = PortP->TtyP;*/ /* Get tty */
543 tty = PortP->gs.tty;
544 rio_dprintk (RIO_DEBUG_TTY, "TTY is at address 0x%x\n",(int)tty);
545
546 if (PortP->gs.closing_wait)
547 end_time = jiffies + PortP->gs.closing_wait;
548 else
549 end_time = jiffies + MAX_SCHEDULE_TIMEOUT;
550
551 Modem = rio_ismodem(tty);
552#if 0
553 /* What F.CKING cache? Even then, a higly idle multiprocessor,
554 system with large caches this won't work . Better find out when
555 this doesn't work asap, and fix the cause. -- REW */
556
557 RIODelay(PortP, HUNDRED_MS*10); /* To flush the cache */
558#endif
559 rio_spin_lock_irqsave(&PortP->portSem, flags);
560
561 /*
562 ** Setting this flag will make any process trying to open
563 ** this port block until we are complete closing it.
564 */
565 PortP->State |= RIO_CLOSING;
566
567 if ( (PortP->State & RIO_DELETED) ) {
568 rio_dprintk (RIO_DEBUG_TTY, "Close on deleted RTA\n");
569 deleted = 1;
570 }
571
572 if ( p->RIOHalted ) {
573 RIOClearUp( PortP );
574 rv = -EIO;
575 goto close_end;
576 }
577
578 rio_dprintk (RIO_DEBUG_TTY, "Clear bits\n");
579 /*
580 ** clear the open bits for this device
581 */
582 PortP->State &= (Modem ? ~RIO_MOPEN : ~RIO_LOPEN);
583 PortP->State &= ~RIO_CARR_ON;
584 PortP->ModemState &= ~MSVR1_CD;
585 /*
586 ** If the device was open as both a Modem and a tty line
587 ** then we need to wimp out here, as the port has not really
588 ** been finally closed (gee, whizz!) The test here uses the
589 ** bit for the OTHER mode of operation, to see if THAT is
590 ** still active!
591 */
592 if ( (PortP->State & (RIO_LOPEN|RIO_MOPEN)) ) {
593 /*
594 ** The port is still open for the other task -
595 ** return, pretending that we are still active.
596 */
597 rio_dprintk (RIO_DEBUG_TTY, "Channel %d still open !\n",PortP->PortNum);
598 PortP->State &= ~RIO_CLOSING;
599 if (PortP->firstOpen)
600 PortP->firstOpen--;
601 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
602 return -EIO;
603 }
604
605 rio_dprintk (RIO_DEBUG_TTY, "Closing down - everything must go!\n");
606
607 PortP->State &= ~RIO_DYNOROD;
608
609 /*
610 ** This is where we wait for the port
611 ** to drain down before closing. Bye-bye....
612 ** (We never meant to do this)
613 */
614 rio_dprintk (RIO_DEBUG_TTY, "Timeout 1 starts\n");
615
616 if (!deleted)
617 while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted &&
618 (PortP->TxBufferIn != PortP->TxBufferOut) ) {
619 cprintf("Need to flush the ttyport\n");
620 if (repeat_this -- <= 0) {
621 rv = -EINTR;
622 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
623 RIOPreemptiveCmd(p, PortP, FCLOSE );
624 goto close_end;
625 }
626 rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
627 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
628 if (RIODelay_ni(PortP, HUNDRED_MS*10) == RIO_FAIL) {
629 rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
630 rv = -EINTR;
631 rio_spin_lock_irqsave(&PortP->portSem, flags);
632 goto close_end;
633 }
634 rio_spin_lock_irqsave(&PortP->portSem, flags);
635 }
636
637 PortP->TxBufferIn = PortP->TxBufferOut = 0;
638 repeat_this = 0xff;
639
640 PortP->InUse = 0;
641 if ( (PortP->State & (RIO_LOPEN|RIO_MOPEN)) ) {
642 /*
643 ** The port has been re-opened for the other task -
644 ** return, pretending that we are still active.
645 */
646 rio_dprintk (RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum);
647 PortP->State &= ~RIO_CLOSING;
648 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
649 if (PortP->firstOpen)
650 PortP->firstOpen--;
651 return -EIO;
652 }
653
654 if ( p->RIOHalted ) {
655 RIOClearUp( PortP );
656 goto close_end;
657 }
658
659
660
661 /* Can't call RIOShortCommand with the port locked. */
662 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
663
664 if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
665 RIOPreemptiveCmd(p, PortP,FCLOSE);
666 goto close_end;
667 }
668
669 if (!deleted)
670 while (try && (PortP->PortState & PORT_ISOPEN)) {
671 try--;
672 if (time_after (jiffies, end_time)) {
673 rio_dprintk (RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n" );
674 RIOPreemptiveCmd(p, PortP,FCLOSE);
675 break;
676 }
677 rio_dprintk (RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n",
678 PortP->PortState & PORT_ISOPEN);
679
680 if ( p->RIOHalted ) {
681 RIOClearUp( PortP );
682 goto close_end;
683 }
684 if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
685 rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
686 RIOPreemptiveCmd(p, PortP,FCLOSE);
687 break;
688 }
689 }
690 rio_spin_lock_irqsave(&PortP->portSem, flags);
691 rio_dprintk (RIO_DEBUG_TTY, "Close: try was %d on completion\n", try );
692
693 /* RIOPreemptiveCmd(p, PortP, FCLOSE); */
694
695/*
696** 15.10.1998 ARG - ESIL 0761 part fix
697** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened.
698*/
699 PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
700
701
702#ifdef STATS
703 PortP->Stat.CloseCnt++;
704#endif
705 /*
706 ** Count opens for port statistics reporting
707 */
708 if (PortP->statsGather)
709 PortP->closes++;
710
711close_end:
712 /* XXX: Why would a "DELETED" flag be reset here? I'd have
713 thought that a "deleted" flag means that the port was
714 permanently gone, but here we can make it reappear by it
715 being in close during the "deletion".
716 */
717 PortP->State &= ~(RIO_CLOSING|RIO_DELETED);
718 if (PortP->firstOpen)
719 PortP->firstOpen--;
720 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
721 rio_dprintk (RIO_DEBUG_TTY, "Return from close\n");
722 return rv;
723}
724
725
726/*
727** decide if we need to use the line discipline.
728** This routine can return one of three values:
729** COOK_RAW if no processing has to be done by the line discipline or the card
730** COOK_WELL if the line discipline must be used to do the processing
731** COOK_MEDIUM if the card can do all the processing necessary.
732*/
733#if 0
734static int
735RIOCookMode(struct ttystatics *tp)
736{
737 /*
738 ** We can't handle tm.c_mstate != 0 on SCO
739 ** We can't handle mapping
740 ** We can't handle non-ttwrite line disc.
741 ** We can't handle lflag XCASE
742 ** We can handle oflag OPOST & (OCRNL, ONLCR, TAB3)
743 */
744
745#ifdef CHECK
746 CheckTtyP( tp );
747#endif
748 if (!(tp->tm.c_oflag & OPOST)) /* No post processing */
749 return COOK_RAW; /* Raw mode o/p */
750
751 if ( tp->tm.c_lflag & XCASE )
752 return COOK_WELL; /* Use line disc */
753
754 if (tp->tm.c_oflag & ~(OPOST | ONLCR | OCRNL | TAB3 ) )
755 return COOK_WELL; /* Use line disc for strange modes */
756
757 if ( tp->tm.c_oflag == OPOST ) /* If only OPOST is set, do RAW */
758 return COOK_RAW;
759
760 /*
761 ** So, we need to output process!
762 */
763 return COOK_MEDIUM;
764}
765#endif
766
767static void
768RIOClearUp(PortP)
769struct Port *PortP;
770{
771 rio_dprintk (RIO_DEBUG_TTY, "RIOHalted set\n");
772 PortP->Config = 0; /* Direct semaphore */
773 PortP->PortState = 0;
774 PortP->firstOpen = 0;
775 PortP->FlushCmdBodge = 0;
776 PortP->ModemState = PortP->CookMode = 0;
777 PortP->Mapped = 0;
778 PortP->WflushFlag = 0;
779 PortP->MagicFlags = 0;
780 PortP->RxDataStart = 0;
781 PortP->TxBufferIn = 0;
782 PortP->TxBufferOut = 0;
783}
784
785/*
786** Put a command onto a port.
787** The PortPointer, command, length and arg are passed.
788** The len is the length *inclusive* of the command byte,
789** and so for a command that takes no data, len==1.
790** The arg is a single byte, and is only used if len==2.
791** Other values of len aren't allowed, and will cause
792** a panic.
793*/
794int RIOShortCommand(struct rio_info *p, struct Port *PortP,
795 int command, int len, int arg)
796{
797 PKT *PacketP;
798 int retries = 20; /* at 10 per second -> 2 seconds */
799 unsigned long flags;
800
801 rio_dprintk (RIO_DEBUG_TTY, "entering shortcommand.\n");
802#ifdef CHECK
803 CheckPortP( PortP );
804 if ( len < 1 || len > 2 )
805 cprintf(("STUPID LENGTH %d\n",len));
806#endif
807
808 if ( PortP->State & RIO_DELETED ) {
809 rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
810 return RIO_FAIL;
811 }
812 rio_spin_lock_irqsave(&PortP->portSem, flags);
813
814 /*
815 ** If the port is in use for pre-emptive command, then wait for it to
816 ** be free again.
817 */
818 while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted ) {
819 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not in use (%d)\n",
820 retries);
821 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
822 if (retries-- <= 0) {
823 return RIO_FAIL;
824 }
825 if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) {
826 return RIO_FAIL;
827 }
828 rio_spin_lock_irqsave(&PortP->portSem, flags);
829 }
830 if ( PortP->State & RIO_DELETED ) {
831 rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
832 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
833 return RIO_FAIL;
834 }
835
836 while ( !can_add_transmit(&PacketP,PortP) && !p->RIOHalted ) {
837 rio_dprintk (RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries);
838 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
839 if (retries-- <= 0) {
840 rio_dprintk (RIO_DEBUG_TTY, "out of tries. Failing\n");
841 return RIO_FAIL;
842 }
843 if ( RIODelay_ni(PortP, HUNDRED_MS)==RIO_FAIL ) {
844 return RIO_FAIL;
845 }
846 rio_spin_lock_irqsave(&PortP->portSem, flags);
847 }
848
849 if ( p->RIOHalted ) {
850 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
851 return RIO_FAIL;
852 }
853
854 /*
855 ** set the command byte and the argument byte
856 */
857 WBYTE(PacketP->data[0] , command);
858
859 if ( len==2 )
860 WBYTE(PacketP->data[1] , arg);
861
862 /*
863 ** set the length of the packet and set the command bit.
864 */
865 WBYTE(PacketP->len , PKT_CMD_BIT | len);
866
867 add_transmit(PortP);
868 /*
869 ** Count characters transmitted for port statistics reporting
870 */
871 if (PortP->statsGather)
872 PortP->txchars += len;
873
874 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
875 return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL;
876}
877
878
879#if 0
880/*
881** This is an ioctl interface. This is the twentieth century. You know what
882** its all about.
883*/
884int
885riotioctl(struct rio_info *p, struct tty_struct *tty, int cmd, caddr_t arg)
886{
887 register struct Port *PortP;
888 register struct ttystatics *tp;
889 int current;
890 int ParamSemIncremented = 0;
891 int old_oflag, old_cflag, old_iflag, changed, oldcook;
892 int i;
893 unsigned char sio_regs[5]; /* Here be magic */
894 short vpix_cflag;
895 short divisor;
896 int baud;
897 uint SysPort = rio_minor(tty);
898 int Modem = rio_ismodem(tty);
899 int ioctl_processed;
900
901 rio_dprintk (RIO_DEBUG_TTY, "port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
902 SysPort, cmd, arg, Modem?"Modem":"tty") ;
903
904 if ( SysPort >= RIO_PORTS ) {
905 rio_dprintk (RIO_DEBUG_TTY, "Bad port number %d\n", SysPort);
906 return -ENXIO;
907 }
908
909 PortP = p->RIOPortp[SysPort];
910 tp = PortP->TtyP;
911
912 rio_spin_lock_irqsave(&PortP->portSem, flags);
913
914#ifdef STATS
915 PortP->Stat.IoctlCnt++;
916#endif
917
918 if ( PortP->State & RIO_DELETED ) {
919 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
920 return -EIO;
921 }
922
923
924 if ( p->RIOHalted ) {
925 RIOClearUp( PortP );
926 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
927 return -EIO;
928 }
929
930 /*
931 ** Count ioctls for port statistics reporting
932 */
933 if (PortP->statsGather)
934 PortP->ioctls++;
935
936 /*
937 ** Specialix RIO Ioctl calls
938 */
939 switch (cmd) {
940
941 case TCRIOTRIAD:
942 if ( arg )
943 PortP->State |= RIO_TRIAD_MODE;
944 else
945 PortP->State &= ~RIO_TRIAD_MODE;
946 /*
947 ** Normally, when istrip is set on a port, a config is
948 ** sent to the RTA instructing the CD1400 to do the
949 ** stripping. In TRIAD mode, the interrupt receive routine
950 ** must do the stripping instead, since it has to detect
951 ** an 8 bit function key sequence. If istrip is set with
952 ** TRIAD mode on(off), and 8 bit data is being read by
953 ** the port, the user then turns TRIAD mode off(on), the RTA
954 ** must be reconfigured (not) to do the stripping.
955 ** Hence we call RIOParam here.
956 */
957 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
958 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
959 return 0;
960
961 case TCRIOTSTATE:
962 rio_dprintk (RIO_DEBUG_TTY, "tbusy/tstop monitoring %sabled\n",
963 arg ? "en" : "dis");
964 /* MonitorTstate = 0 ;*/
965 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
966 RIOParam(PortP, CONFIG, Modem, OK_TO_SLEEP);
967 return 0;
968
969 case TCRIOSTATE: /* current state of Modem input pins */
970 rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE\n");
971 if (RIOPreemptiveCmd(p, PortP, MGET) == RIO_FAIL)
972 rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE command failed\n");
973 PortP->State |= RIO_BUSY;
974 current = PortP->ModemState;
975 if ( copyout((caddr_t)&current, (int)arg,
976 sizeof(current))==COPYFAIL ) {
977 rio_dprintk (RIO_DEBUG_TTY, "Copyout failed\n");
978 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
979 pseterr(EFAULT);
980 }
981 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
982 return 0;
983
984 case TCRIOMBIS: /* Set modem lines */
985 case TCRIOMBIC: /* Clear modem lines */
986 rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIS/TCRIOMBIC\n");
987 if (cmd == TCRIOMBIS) {
988 uint state;
989 state = (uint)arg;
990 PortP->ModemState |= (ushort)state;
991 PortP->ModemLines = (ulong) arg;
992 if (RIOPreemptiveCmd(p, PortP, MBIS) == RIO_FAIL)
993 rio_dprintk (RIO_DEBUG_TTY,
994 "TCRIOMBIS command failed\n");
995 }
996 else {
997 uint state;
998
999 state = (uint)arg;
1000 PortP->ModemState &= ~(ushort)state;
1001 PortP->ModemLines = (ulong) arg;
1002 if (RIOPreemptiveCmd(p, PortP, MBIC) == RIO_FAIL)
1003 rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIC command failed\n");
1004 }
1005 PortP->State |= RIO_BUSY;
1006 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1007 return 0;
1008
1009 case TCRIOXPON: /* set Xprint ON string */
1010 rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPON\n");
1011 if ( copyin((int)arg, (caddr_t)PortP->Xprint.XpOn,
1012 MAX_XP_CTRL_LEN)==COPYFAIL ) {
1013 rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
1014 PortP->Xprint.XpOn[0] = '\0';
1015 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1016 pseterr(EFAULT);
1017 }
1018 PortP->Xprint.XpOn[MAX_XP_CTRL_LEN-1] = '\0';
1019 PortP->Xprint.XpLen = strlen(PortP->Xprint.XpOn)+
1020 strlen(PortP->Xprint.XpOff);
1021 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1022 return 0;
1023
1024 case TCRIOXPOFF: /* set Xprint OFF string */
1025 rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPOFF\n");
1026 if ( copyin( (int)arg, (caddr_t)PortP->Xprint.XpOff,
1027 MAX_XP_CTRL_LEN)==COPYFAIL ) {
1028 rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
1029 PortP->Xprint.XpOff[0] = '\0';
1030 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1031 pseterr(EFAULT);
1032 }
1033 PortP->Xprint.XpOff[MAX_XP_CTRL_LEN-1] = '\0';
1034 PortP->Xprint.XpLen = strlen(PortP->Xprint.XpOn)+
1035 strlen(PortP->Xprint.XpOff);
1036 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1037 return 0;
1038
1039 case TCRIOXPCPS: /* set Xprint CPS string */
1040 rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPCPS\n");
1041 if ( (uint)arg > p->RIOConf.MaxXpCps ||
1042 (uint)arg < p->RIOConf.MinXpCps ) {
1043 rio_dprintk (RIO_DEBUG_TTY, "%d CPS out of range\n",arg);
1044 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1045 pseterr(EINVAL);
1046 return 0;
1047 }
1048 PortP->Xprint.XpCps = (uint)arg;
1049 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1050 return 0;
1051
1052 case TCRIOXPRINT:
1053 rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPRINT\n");
1054 if ( copyout((caddr_t)&PortP->Xprint, (int)arg,
1055 sizeof(struct Xprint))==COPYFAIL ) {
1056 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1057 pseterr(EFAULT);
1058 }
1059 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1060 return 0;
1061
1062 case TCRIOIXANYON:
1063 rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYON\n");
1064 PortP->Config |= RIO_IXANY;
1065 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1066 return 0;
1067
1068 case TCRIOIXANYOFF:
1069 rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYOFF\n");
1070 PortP->Config &= ~RIO_IXANY;
1071 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1072 return 0;
1073
1074 case TCRIOIXONON:
1075 rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONON\n");
1076 PortP->Config |= RIO_IXON;
1077 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1078 return 0;
1079
1080 case TCRIOIXONOFF:
1081 rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONOFF\n");
1082 PortP->Config &= ~RIO_IXON;
1083 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1084 return 0;
1085
1086/*
1087** 15.10.1998 ARG - ESIL 0761 part fix
1088** Added support for CTS and RTS flow control ioctls :
1089*/
1090 case TCRIOCTSFLOWEN:
1091 rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWEN\n");
1092 PortP->Config |= RIO_CTSFLOW;
1093 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1094 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
1095 return 0;
1096
1097 case TCRIOCTSFLOWDIS:
1098 rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWDIS\n");
1099 PortP->Config &= ~RIO_CTSFLOW;
1100 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1101 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
1102 return 0;
1103
1104 case TCRIORTSFLOWEN:
1105 rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWEN\n");
1106 PortP->Config |= RIO_RTSFLOW;
1107 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1108 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
1109 return 0;
1110
1111 case TCRIORTSFLOWDIS:
1112 rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWDIS\n");
1113 PortP->Config &= ~RIO_RTSFLOW;
1114 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1115 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
1116 return 0;
1117
1118/* end ESIL 0761 part fix */
1119
1120 }
1121
1122
1123 /* Lynx IOCTLS */
1124 switch (cmd) {
1125 case TIOCSETP:
1126 case TIOCSETN:
1127 case OTIOCSETP:
1128 case OTIOCSETN:
1129 ioctl_processed++;
1130 ttyseth(PortP, tp, (struct old_sgttyb *)arg);
1131 break;
1132 case TCSETA:
1133 case TCSETAW:
1134 case TCSETAF:
1135 ioctl_processed++;
1136 rio_dprintk (RIO_DEBUG_TTY, "NON POSIX ioctl\n");
1137 ttyseth_pv(PortP, tp, (struct termios *)arg, 0);
1138 break;
1139 case TCSETAP: /* posix tcsetattr() */
1140 case TCSETAWP: /* posix tcsetattr() */
1141 case TCSETAFP: /* posix tcsetattr() */
1142 rio_dprintk (RIO_DEBUG_TTY, "NON POSIX SYSV ioctl\n");
1143 ttyseth_pv(PortP, tp, (struct termios *)arg, 1);
1144 ioctl_processed++;
1145 break;
1146 }
1147
1148 /*
1149 ** If its any of the commands that require the port to be in the
1150 ** non-busy state wait until all output has drained
1151 */
1152 if (!ioctl_processed)
1153 switch(cmd) {
1154 case TCSETAW:
1155 case TCSETAF:
1156 case TCSETA:
1157 case TCSBRK:
1158#define OLD_POSIX ('x' << 8)
1159#define OLD_POSIX_SETA (OLD_POSIX | 2)
1160#define OLD_POSIX_SETAW (OLD_POSIX | 3)
1161#define OLD_POSIX_SETAF (OLD_POSIX | 4)
1162#define NEW_POSIX (('i' << 24) | ('X' << 16))
1163#define NEW_POSIX_SETA (NEW_POSIX | 2)
1164#define NEW_POSIX_SETAW (NEW_POSIX | 3)
1165#define NEW_POSIX_SETAF (NEW_POSIX | 4)
1166 case OLD_POSIX_SETA:
1167 case OLD_POSIX_SETAW:
1168 case OLD_POSIX_SETAF:
1169 case NEW_POSIX_SETA:
1170 case NEW_POSIX_SETAW:
1171 case NEW_POSIX_SETAF:
1172#ifdef TIOCSETP
1173 case TIOCSETP:
1174#endif
1175 case TIOCSETD:
1176 case TIOCSETN:
1177 rio_dprintk (RIO_DEBUG_TTY, "wait for non-BUSY, semaphore set\n");
1178 /*
1179 ** Wait for drain here, at least as far as the double buffer
1180 ** being empty.
1181 */
1182 /* XXX Does the above comment mean that this has
1183 still to be implemented? -- REW */
1184 /* XXX Is the locking OK together with locking
1185 in txenable? (Deadlock?) -- REW */
1186
1187 RIOTxEnable((char *)PortP);
1188 break;
1189 default:
1190 break;
1191 }
1192
1193 old_cflag = tp->tm.c_cflag;
1194 old_iflag = tp->tm.c_iflag;
1195 old_oflag = tp->tm.c_oflag;
1196 oldcook = PortP->CookMode;
1197
1198 if ( p->RIOHalted ) {
1199 RIOClearUp( PortP );
1200 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1201 pseterr(EIO);
1202 return 0;
1203 }
1204
1205 PortP->FlushCmdBodge = 0;
1206
1207 /*
1208 ** If the port is locked, and it is reconfigured, we want
1209 ** to restore the state of the tty structure so the change is NOT
1210 ** made.
1211 */
1212 if (PortP->Lock) {
1213 tp->tm.c_iflag = PortP->StoredTty.iflag;
1214 tp->tm.c_oflag = PortP->StoredTty.oflag;
1215 tp->tm.c_cflag = PortP->StoredTty.cflag;
1216 tp->tm.c_lflag = PortP->StoredTty.lflag;
1217 tp->tm.c_line = PortP->StoredTty.line;
1218 for (i = 0; i < NCC + 1; i++)
1219 tp->tm.c_cc[i] = PortP->StoredTty.cc[i];
1220 }
1221 else {
1222 /*
1223 ** If the port is set to store the parameters, and it is
1224 ** reconfigured, we want to save the current tty struct so it
1225 ** may be restored on the next open.
1226 */
1227 if (PortP->Store) {
1228 PortP->StoredTty.iflag = tp->tm.c_iflag;
1229 PortP->StoredTty.oflag = tp->tm.c_oflag;
1230 PortP->StoredTty.cflag = tp->tm.c_cflag;
1231 PortP->StoredTty.lflag = tp->tm.c_lflag;
1232 PortP->StoredTty.line = tp->tm.c_line;
1233 for (i = 0; i < NCC + 1; i++)
1234 PortP->StoredTty.cc[i] = tp->tm.c_cc[i];
1235 }
1236 }
1237
1238 changed = (tp->tm.c_cflag != old_cflag) ||
1239 (tp->tm.c_iflag != old_iflag) ||
1240 (tp->tm.c_oflag != old_oflag);
1241
1242 PortP->CookMode = RIOCookMode(tp); /* Set new cooking mode */
1243
1244 rio_dprintk (RIO_DEBUG_TTY, "RIOIoctl changed %d newcook %d oldcook %d\n",
1245 changed,PortP->CookMode,oldcook);
1246
1247#ifdef MODEM_SUPPORT
1248 /*
1249 ** kludge to force CARR_ON if CLOCAL set
1250 */
1251 if ((tp->tm.c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD)) {
1252 tp->tm.c_state |= CARR_ON;
1253 wakeup ((caddr_t)&tp->tm.c_canq);
1254 }
1255#endif
1256
1257 if ( p->RIOHalted ) {
1258 RIOClearUp( PortP );
1259 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1260 pseterr(EIO);
1261 return 0;
1262 }
1263 /*
1264 ** Re-configure if modes or cooking have changed
1265 */
1266 if (changed || oldcook != PortP->CookMode || (ioctl_processed)) {
1267 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1268 rio_dprintk (RIO_DEBUG_TTY, "Ioctl changing the PORT settings\n");
1269 RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);
1270 rio_spin_lock_irqsave(&PortP->portSem, flags);
1271 }
1272
1273 if (p->RIOHalted) {
1274 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1275 RIOClearUp( PortP );
1276 pseterr(EIO);
1277 return 0;
1278 }
1279 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1280 return 0;
1281}
1282
1283/*
1284 ttyseth -- set hardware dependent tty settings
1285*/
1286void
1287ttyseth(PortP, s, sg)
1288struct Port * PortP;
1289struct ttystatics * s;
1290struct old_sgttyb *sg;
1291{
1292 struct old_sgttyb * tsg;
1293 struct termios *tp = &s->tm;
1294
1295 tsg = &s->sg;
1296
1297 if (sg->sg_flags & (EVENP|ODDP)) {
1298 tp->c_cflag &= PARENB;
1299 if (sg->sg_flags & EVENP) {
1300 if (sg->sg_flags & ODDP) {
1301 tp->c_cflag &= V_CS7;
1302 tp->c_cflag &= ~PARENB;
1303 }
1304 else {
1305 tp->c_cflag &= V_CS7;
1306 tp->c_cflag &= PARENB;
1307 tp->c_cflag &= PARODD;
1308 }
1309 }
1310 else if (sg->sg_flags & ODDP) {
1311 tp->c_cflag &= V_CS7;
1312 tp->c_cflag &= PARENB;
1313 tp->c_cflag &= PARODD;
1314 }
1315 else {
1316 tp->c_cflag &= V_CS7;
1317 tp->c_cflag &= PARENB;
1318 }
1319 }
1320/*
1321 * Use ispeed as the desired speed. Most implementations don't handle
1322 * separate input and output speeds very well. If the RIO handles this,
1323 * I will have to use separate sets of flags to store them in the
1324 * Port structure.
1325 */
1326 if ( !sg->sg_ospeed )
1327 sg->sg_ospeed = sg->sg_ispeed;
1328 else
1329 sg->sg_ispeed = sg->sg_ospeed;
1330 if (sg->sg_ispeed > V_EXTB )
1331 sg->sg_ispeed = V_EXTB;
1332 if (sg->sg_ispeed < V_B0)
1333 sg->sg_ispeed = V_B0;
1334 *tsg = *sg;
1335 tp->c_cflag = (tp->c_cflag & ~V_CBAUD) | conv_bv[(int)sg->sg_ispeed];
1336}
1337
1338/*
1339 ttyseth_pv -- set hardware dependent tty settings using either the
1340 POSIX termios structure or the System V termio structure.
1341 sysv = 0 => (POSIX): struct termios *sg
1342 sysv != 0 => (System V): struct termio *sg
1343*/
1344static void
1345ttyseth_pv(PortP, s, sg, sysv)
1346struct Port *PortP;
1347struct ttystatics *s;
1348struct termios *sg;
1349int sysv;
1350{
1351 int speed;
1352 unsigned char csize;
1353 unsigned char cread;
1354 unsigned int lcr_flags;
1355 int ps;
1356
1357 if (sysv) {
1358 /* sg points to a System V termio structure */
1359 csize = ((struct termio *)sg)->c_cflag & CSIZE;
1360 cread = ((struct termio *)sg)->c_cflag & CREAD;
1361 speed = conv_vb[((struct termio *)sg)->c_cflag & V_CBAUD];
1362 }
1363 else {
1364 /* sg points to a POSIX termios structure */
1365 csize = sg->c_cflag & CSIZE;
1366 cread = sg->c_cflag & CREAD;
1367 speed = conv_vb[sg->c_cflag & V_CBAUD];
1368 }
1369 if (s->sg.sg_ispeed != speed || s->sg.sg_ospeed != speed) {
1370 s->sg.sg_ispeed = speed;
1371 s->sg.sg_ospeed = speed;
1372 s->tm.c_cflag = (s->tm.c_cflag & ~V_CBAUD) |
1373 conv_bv[(int)s->sg.sg_ispeed];
1374 }
1375}
1376#endif
diff --git a/drivers/char/rio/riotypes.h b/drivers/char/rio/riotypes.h
new file mode 100644
index 000000000000..1c7c42c638f0
--- /dev/null
+++ b/drivers/char/rio/riotypes.h
@@ -0,0 +1,135 @@
1/****************************************************************************
2 ******* *******
3 ******* R I O T Y P E S
4 ******* *******
5 ****************************************************************************
6
7 Author : Jon Brawn
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _riotypes_h
38#define _riotypes_h 1
39
40#ifdef SCCS_LABELS
41#ifndef lint
42/* static char *_rio_riotypes_h_sccs = "@(#)riotypes.h 1.10"; */
43#endif
44#endif
45
46#ifdef INKERNEL
47
48#if !defined(MIPSAT)
49typedef unsigned short NUMBER_ptr;
50typedef unsigned short WORD_ptr;
51typedef unsigned short BYTE_ptr;
52typedef unsigned short char_ptr;
53typedef unsigned short Channel_ptr;
54typedef unsigned short FREE_LIST_ptr_ptr;
55typedef unsigned short FREE_LIST_ptr;
56typedef unsigned short LPB_ptr;
57typedef unsigned short Process_ptr;
58typedef unsigned short PHB_ptr;
59typedef unsigned short PKT_ptr;
60typedef unsigned short PKT_ptr_ptr;
61typedef unsigned short Q_BUF_ptr;
62typedef unsigned short Q_BUF_ptr_ptr;
63typedef unsigned short ROUTE_STR_ptr;
64typedef unsigned short RUP_ptr;
65typedef unsigned short short_ptr;
66typedef unsigned short u_short_ptr;
67typedef unsigned short ushort_ptr;
68#else
69/* MIPSAT types */
70typedef char RIO_POINTER[8];
71typedef RIO_POINTER NUMBER_ptr;
72typedef RIO_POINTER WORD_ptr;
73typedef RIO_POINTER BYTE_ptr;
74typedef RIO_POINTER char_ptr;
75typedef RIO_POINTER Channel_ptr;
76typedef RIO_POINTER FREE_LIST_ptr_ptr;
77typedef RIO_POINTER FREE_LIST_ptr;
78typedef RIO_POINTER LPB_ptr;
79typedef RIO_POINTER Process_ptr;
80typedef RIO_POINTER PHB_ptr;
81typedef RIO_POINTER PKT_ptr;
82typedef RIO_POINTER PKT_ptr_ptr;
83typedef RIO_POINTER Q_BUF_ptr;
84typedef RIO_POINTER Q_BUF_ptr_ptr;
85typedef RIO_POINTER ROUTE_STR_ptr;
86typedef RIO_POINTER RUP_ptr;
87typedef RIO_POINTER short_ptr;
88typedef RIO_POINTER u_short_ptr;
89typedef RIO_POINTER ushort_ptr;
90#endif
91
92#else /* not INKERNEL */
93typedef unsigned char BYTE;
94typedef unsigned short WORD;
95typedef unsigned long DWORD;
96typedef short NUMBER;
97typedef short *NUMBER_ptr;
98typedef unsigned short *WORD_ptr;
99typedef unsigned char *BYTE_ptr;
100typedef unsigned char uchar ;
101typedef unsigned short ushort ;
102typedef unsigned int uint ;
103typedef unsigned long ulong ;
104typedef unsigned char u_char ;
105typedef unsigned short u_short ;
106typedef unsigned int u_int ;
107typedef unsigned long u_long ;
108typedef unsigned short ERROR ;
109typedef unsigned long ID ;
110typedef char *char_ptr;
111typedef Channel *Channel_ptr;
112typedef struct FREE_LIST *FREE_LIST_ptr;
113typedef struct FREE_LIST **FREE_LIST_ptr_ptr;
114typedef struct LPB *LPB_ptr;
115typedef struct Process *Process_ptr;
116typedef struct PHB *PHB_ptr;
117typedef struct PKT *PKT_ptr;
118typedef struct PKT **PKT_ptr_ptr;
119typedef struct Q_BUF *Q_BUF_ptr;
120typedef struct Q_BUF **Q_BUF_ptr_ptr;
121typedef struct ROUTE_STR *ROUTE_STR_ptr;
122typedef struct RUP *RUP_ptr;
123typedef short *short_ptr;
124typedef u_short *u_short_ptr;
125typedef ushort *ushort_ptr;
126typedef struct PKT PKT;
127typedef struct LPB LPB;
128typedef struct RUP RUP;
129#endif
130
131
132#endif /* __riotypes__ */
133
134/*********** end of file ***********/
135
diff --git a/drivers/char/rio/riowinif.h b/drivers/char/rio/riowinif.h
new file mode 100644
index 000000000000..18a4f147edc2
--- /dev/null
+++ b/drivers/char/rio/riowinif.h
@@ -0,0 +1,1335 @@
1/************************************************************************/
2/* */
3/* Title : RIO Shared Memory Window Inteface */
4/* */
5/* Author : N.P.Vassallo */
6/* */
7/* Creation : 7th June 1999 */
8/* */
9/* Version : 1.0.0 */
10/* */
11/* Copyright : (c) Specialix International Ltd. 1999 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * */
26/* Description : Prototypes, structures and definitions */
27/* describing RIO host card shared memory */
28/* window interface structures: */
29/* PARMMAP */
30/* RUP */
31/* PHB */
32/* LPB */
33/* PKT */
34/* */
35/************************************************************************/
36
37/* History...
38
391.0.0 07/06/99 NPV Creation. (based on PARMMAP.H)
40
41*/
42
43#ifndef _riowinif_h /* If RIOWINDIF.H not already defined */
44#define _riowinif_h 1
45
46/*****************************************************************************
47******************************** *********************************
48******************************** General *********************************
49******************************** *********************************
50*****************************************************************************/
51
52#define TPNULL ((_u16)(0x8000))
53
54/*****************************************************************************
55******************************** ********************************
56******************************** PARM_MAP ********************************
57******************************** ********************************
58*****************************************************************************/
59
60/* The PARM_MAP structure defines global values relating to the Host Card / RTA
61 and is the main structure from which all other structures are referenced. */
62
63typedef struct _PARM_MAP
64{
65 _u16 phb_ptr; /* 0x00 Pointer to the PHB array */
66 _u16 phb_num_ptr; /* 0x02 Ptr to Number of PHB's */
67 _u16 free_list; /* 0x04 Free List pointer */
68 _u16 free_list_end; /* 0x06 Free List End pointer */
69 _u16 q_free_list_ptr; /* 0x08 Ptr to Q_BUF variable */
70 _u16 unit_id_ptr; /* 0x0A Unit Id */
71 _u16 link_str_ptr; /* 0x0C Link Structure Array */
72 _u16 bootloader_1; /* 0x0E 1st Stage Boot Loader */
73 _u16 bootloader_2; /* 0x10 2nd Stage Boot Loader */
74 _u16 port_route_map_ptr; /* 0x12 Port Route Map */
75 _u16 route_ptr; /* 0x14 Route Map */
76 _u16 map_present; /* 0x16 Route Map present */
77 _u16 pkt_num; /* 0x18 Total number of packets */
78 _u16 q_num; /* 0x1A Total number of Q packets */
79 _u16 buffers_per_port; /* 0x1C Number of buffers per port */
80 _u16 heap_size; /* 0x1E Initial size of heap */
81 _u16 heap_left; /* 0x20 Current Heap left */
82 _u16 error; /* 0x22 Error code */
83 _u16 tx_max; /* 0x24 Max number of tx pkts per phb */
84 _u16 rx_max; /* 0x26 Max number of rx pkts per phb */
85 _u16 rx_limit; /* 0x28 For high / low watermarks */
86 _u16 links; /* 0x2A Links to use */
87 _u16 timer; /* 0x2C Interrupts per second */
88 _u16 rups; /* 0x2E Pointer to the RUPs */
89 _u16 max_phb; /* 0x30 Mostly for debugging */
90 _u16 living; /* 0x32 Just increments!! */
91 _u16 init_done; /* 0x34 Initialisation over */
92 _u16 booting_link; /* 0x36 */
93 _u16 idle_count; /* 0x38 Idle time counter */
94 _u16 busy_count; /* 0x3A Busy counter */
95 _u16 idle_control; /* 0x3C Control Idle Process */
96 _u16 tx_intr; /* 0x3E TX interrupt pending */
97 _u16 rx_intr; /* 0x40 RX interrupt pending */
98 _u16 rup_intr; /* 0x42 RUP interrupt pending */
99
100} PARM_MAP;
101
102/* Same thing again, but defined as offsets... */
103
104#define PM_phb_ptr 0x00 /* 0x00 Pointer to the PHB array */
105#define PM_phb_num_ptr 0x02 /* 0x02 Ptr to Number of PHB's */
106#define PM_free_list 0x04 /* 0x04 Free List pointer */
107#define PM_free_list_end 0x06 /* 0x06 Free List End pointer */
108#define PM_q_free_list_ptr 0x08 /* 0x08 Ptr to Q_BUF variable */
109#define PM_unit_id_ptr 0x0A /* 0x0A Unit Id */
110#define PM_link_str_ptr 0x0C /* 0x0C Link Structure Array */
111#define PM_bootloader_1 0x0E /* 0x0E 1st Stage Boot Loader */
112#define PM_bootloader_2 0x10 /* 0x10 2nd Stage Boot Loader */
113#define PM_port_route_map_ptr 0x12 /* 0x12 Port Route Map */
114#define PM_route_ptr 0x14 /* 0x14 Route Map */
115#define PM_map_present 0x16 /* 0x16 Route Map present */
116#define PM_pkt_num 0x18 /* 0x18 Total number of packets */
117#define PM_q_num 0x1A /* 0x1A Total number of Q packets */
118#define PM_buffers_per_port 0x1C /* 0x1C Number of buffers per port */
119#define PM_heap_size 0x1E /* 0x1E Initial size of heap */
120#define PM_heap_left 0x20 /* 0x20 Current Heap left */
121#define PM_error 0x22 /* 0x22 Error code */
122#define PM_tx_max 0x24 /* 0x24 Max number of tx pkts per phb */
123#define PM_rx_max 0x26 /* 0x26 Max number of rx pkts per phb */
124#define PM_rx_limit 0x28 /* 0x28 For high / low watermarks */
125#define PM_links 0x2A /* 0x2A Links to use */
126#define PM_timer 0x2C /* 0x2C Interrupts per second */
127#define PM_rups 0x2E /* 0x2E Pointer to the RUPs */
128#define PM_max_phb 0x30 /* 0x30 Mostly for debugging */
129#define PM_living 0x32 /* 0x32 Just increments!! */
130#define PM_init_done 0x34 /* 0x34 Initialisation over */
131#define PM_booting_link 0x36 /* 0x36 */
132#define PM_idle_count 0x38 /* 0x38 Idle time counter */
133#define PM_busy_count 0x3A /* 0x3A Busy counter */
134#define PM_idle_control 0x3C /* 0x3C Control Idle Process */
135#define PM_tx_intr 0x3E /* 0x4E TX interrupt pending */
136#define PM_rx_intr 0x40 /* 0x40 RX interrupt pending */
137#define PM_rup_intr 0x42 /* 0x42 RUP interrupt pending */
138#define sizeof_PARM_MAP 0x44 /* structure size = 0x44 */
139
140/* PARM_MAP.error definitions... */
141#define E_NO_ERROR 0x00
142#define E_PROCESS_NOT_INIT 0x01
143#define E_LINK_TIMEOUT 0x02
144#define E_NO_ROUTE 0x03
145#define E_CONFUSED 0x04
146#define E_HOME 0x05
147#define E_CSUM_FAIL 0x06
148#define E_DISCONNECTED 0x07
149#define E_BAD_RUP 0x08
150#define E_NO_VIRGIN 0x09
151#define E_BOOT_RUP_BUSY 0x10
152#define E_CHANALLOC 0x80
153#define E_POLL_ALLOC 0x81
154#define E_LTTWAKE 0x82
155#define E_LTT_ALLOC 0x83
156#define E_LRT_ALLOC 0x84
157#define E_CIRRUS 0x85
158#define E_MONITOR 0x86
159#define E_PHB_ALLOC 0x87
160#define E_ARRAY_ALLOC 0x88
161#define E_QBUF_ALLOC 0x89
162#define E_PKT_ALLOC 0x8a
163#define E_GET_TX_Q_BUF 0x8b
164#define E_GET_RX_Q_BUF 0x8c
165#define E_MEM_OUT 0x8d
166#define E_MMU_INIT 0x8e
167#define E_LTT_INIT 0x8f
168#define E_LRT_INIT 0x90
169#define E_LINK_RUN 0x91
170#define E_MONITOR_ALLOC 0x92
171#define E_MONITOR_INIT 0x93
172#define E_POLL_INIT 0x94
173
174/* PARM_MAP.links definitions... */
175#define RIO_LINK_ENABLE 0x80FF
176
177/*****************************************************************************
178********************************** ***********************************
179********************************** RUP ***********************************
180********************************** ***********************************
181*****************************************************************************/
182
183/* The RUP (Remote Unit Port) structure relates to the Remote Terminal Adapters
184 attached to the system and there is normally an array of MAX_RUPS (=16) structures
185 in a host card, defined by PARM_MAP->rup. */
186
187typedef struct _RUP
188{
189 _u16 txpkt; /* 0x00 Outgoing packet */
190 _u16 rxpkt; /* 0x02 ncoming packet */
191 _u16 link; /* 0x04 Which link to send packet down ? */
192 _u8 rup_dest_unit[2]; /* 0x06 Destination Unit */
193 _u16 handshake; /* 0x08 Handshaking */
194 _u16 timeout; /* 0x0A Timeout */
195 _u16 status; /* 0x0C Status */
196 _u16 txcontrol; /* 0x0E Transmit control */
197 _u16 rxcontrol; /* 0x10 Receive control */
198
199} RUP;
200
201/* Same thing again, but defined as offsets... */
202
203#define RUP_txpkt 0x00 /* 0x00 Outgoing packet */
204#define RUP_rxpkt 0x02 /* 0x02 Incoming packet */
205#define RUP_link 0x04 /* 0x04 Which link to send packet down ? */
206#define RUP_rup_dest_unit 0x06 /* 0x06 Destination Unit */
207#define RUP_handshake 0x08 /* 0x08 Handshaking */
208#define RUP_timeout 0x0A /* 0x0A Timeout */
209#define RUP_status 0x0C /* 0x0C Status */
210#define RUP_txcontrol 0x0E /* 0x0E Transmit control */
211#define RUP_rxcontrol 0x10 /* 0x10 Receive control */
212#define sizeof_RUP 0x12 /* structure size = 0x12 */
213
214#define MAX_RUP 16
215
216/* RUP.txcontrol definitions... */
217#define TX_RUP_INACTIVE 0 /* Nothing to transmit */
218#define TX_PACKET_READY 1 /* Transmit packet ready */
219#define TX_LOCK_RUP 2 /* Transmit side locked */
220
221/* RUP.txcontrol definitions... */
222#define RX_RUP_INACTIVE 0 /* Nothing received */
223#define RX_PACKET_READY 1 /* Packet received */
224
225#define RUP_NO_OWNER 0xFF /* RUP not owned by any process */
226
227/*****************************************************************************
228********************************** ***********************************
229********************************** PHB ***********************************
230********************************** ***********************************
231*****************************************************************************/
232
233/* The PHB (Port Header Block) structure relates to the serial ports attached
234 to the system and there is normally an array of MAX_PHBS (=128) structures
235 in a host card, defined by PARM_MAP->phb_ptr and PARM_MAP->phb_num_ptr. */
236
237typedef struct _PHB
238{
239 _u16 source; /* 0x00 Location of the PHB in the host card */
240 _u16 handshake; /* 0x02 Used to manage receive packet flow control */
241 _u16 status; /* 0x04 Internal port transmit/receive status */
242 _u16 timeout; /* 0x06 Time period to wait for an ACK */
243 _u16 link; /* 0x08 The host link associated with the PHB */
244 _u16 destination; /* 0x0A Location of the remote port on the network */
245
246 _u16 tx_start; /* 0x0C first entry in the packet array for transmit packets */
247 _u16 tx_end; /* 0x0E last entry in the packet array for transmit packets */
248 _u16 tx_add; /* 0x10 position in the packet array for new transmit packets */
249 _u16 tx_remove; /* 0x12 current position in the packet pointer array */
250
251 _u16 rx_start; /* 0x14 first entry in the packet array for receive packets */
252 _u16 rx_end; /* 0x16 last entry in the packet array for receive packets */
253 _u16 rx_add; /* 0x18 position in the packet array for new receive packets */
254 _u16 rx_remove; /* 0x1A current position in the packet pointer array */
255
256} PHB;
257
258/* Same thing again, but defined as offsets... */
259
260#define PHB_source 0x00 /* 0x00 Location of the PHB in the host card */
261#define PHB_handshake 0x02 /* 0x02 Used to manage receive packet flow control */
262#define PHB_status 0x04 /* 0x04 Internal port transmit/receive status */
263#define PHB_timeout 0x06 /* 0x06 Time period to wait for an ACK */
264#define PHB_link 0x08 /* 0x08 The host link associated with the PHB */
265#define PHB_destination 0x0A /* 0x0A Location of the remote port on the network */
266#define PHB_tx_start 0x0C /* 0x0C first entry in the packet array for transmit packets */
267#define PHB_tx_end 0x0E /* 0x0E last entry in the packet array for transmit packets */
268#define PHB_tx_add 0x10 /* 0x10 position in the packet array for new transmit packets */
269#define PHB_tx_remove 0x12 /* 0x12 current position in the packet pointer array */
270#define PHB_rx_start 0x14 /* 0x14 first entry in the packet array for receive packets */
271#define PHB_rx_end 0x16 /* 0x16 last entry in the packet array for receive packets */
272#define PHB_rx_add 0x18 /* 0x18 position in the packet array for new receive packets */
273#define PHB_rx_remove 0x1A /* 0x1A current position in the packet pointer array */
274#define sizeof_PHB 0x1C /* structure size = 0x1C */
275
276/* PHB.handshake definitions... */
277#define PHB_HANDSHAKE_SET 0x0001 /* Set by LRT */
278#define PHB_HANDSHAKE_RESET 0x0002 /* Set by ISR / driver */
279#define PHB_HANDSHAKE_FLAGS (PHB_HANDSHAKE_RESET|PHB_HANDSHAKE_SET)
280 /* Reset by ltt */
281
282#define MAX_PHB 128 /* range 0-127 */
283
284/*****************************************************************************
285********************************** ***********************************
286********************************** LPB ***********************************
287********************************** ***********************************
288*****************************************************************************/
289
290/* The LPB (Link Parameter Block) structure relates to a RIO Network Link
291 and there is normally an array of MAX_LINKS (=4) structures in a host card,
292 defined by PARM_MAP->link_str_ptr. */
293
294typedef struct _LPB
295{
296 _u16 link_number; /* 0x00 Link Number */
297 _u16 in_ch; /* 0x02 Link In Channel */
298 _u16 out_ch; /* 0x04 Link Out Channel */
299 _u8 attached_serial[4]; /* 0x06 Attached serial number */
300 _u8 attached_host_serial[4];/* 0x0A Serial number of Host who booted other end */
301 _u16 descheduled; /* 0x0E Currently Descheduled */
302 _u16 state; /* 0x10 Current state */
303 _u16 send_poll; /* 0x12 Send a Poll Packet */
304 _u16 ltt_p; /* 0x14 Process Descriptor */
305 _u16 lrt_p; /* 0x16 Process Descriptor */
306 _u16 lrt_status; /* 0x18 Current lrt status */
307 _u16 ltt_status; /* 0x1A Current ltt status */
308 _u16 timeout; /* 0x1C Timeout value */
309 _u16 topology; /* 0x1E Topology bits */
310 _u16 mon_ltt; /* 0x20 */
311 _u16 mon_lrt; /* 0x22 */
312 _u16 num_pkts; /* 0x24 */
313 _u16 add_packet_list; /* 0x26 Add packets to here */
314 _u16 remove_packet_list; /* 0x28 Send packets from here */
315
316 _u16 lrt_fail_chan; /* 0x2A Lrt's failure channel */
317 _u16 ltt_fail_chan; /* 0x2C Ltt's failure channel */
318
319 RUP rup; /* 0x2E RUP structure for HOST to driver comms */
320 RUP link_rup; /* 0x40 RUP for the link (POLL, topology etc.) */
321 _u16 attached_link; /* 0x52 Number of attached link */
322 _u16 csum_errors; /* 0x54 csum errors */
323 _u16 num_disconnects; /* 0x56 number of disconnects */
324 _u16 num_sync_rcvd; /* 0x58 # sync's received */
325 _u16 num_sync_rqst; /* 0x5A # sync requests */
326 _u16 num_tx; /* 0x5C Num pkts sent */
327 _u16 num_rx; /* 0x5E Num pkts received */
328 _u16 module_attached; /* 0x60 Module tpyes of attached */
329 _u16 led_timeout; /* 0x62 LED timeout */
330 _u16 first_port; /* 0x64 First port to service */
331 _u16 last_port; /* 0x66 Last port to service */
332
333} LPB;
334
335/* Same thing again, but defined as offsets... */
336
337#define LPB_link_number 0x00 /* 0x00 Link Number */
338#define LPB_in_ch 0x02 /* 0x02 Link In Channel */
339#define LPB_out_ch 0x04 /* 0x04 Link Out Channel */
340#define LPB_attached_serial 0x06 /* 0x06 Attached serial number */
341#define LPB_attached_host_serial 0x0A /* 0x0A Serial number of Host who booted other end */
342#define LPB_descheduled 0x0E /* 0x0E Currently Descheduled */
343#define LPB_state 0x10 /* 0x10 Current state */
344#define LPB_send_poll 0x12 /* 0x12 Send a Poll Packet */
345#define LPB_ltt_p 0x14 /* 0x14 Process Descriptor */
346#define LPB_lrt_p 0x16 /* 0x16 Process Descriptor */
347#define LPB_lrt_status 0x18 /* 0x18 Current lrt status */
348#define LPB_ltt_status 0x1A /* 0x1A Current ltt status */
349#define LPB_timeout 0x1C /* 0x1C Timeout value */
350#define LPB_topology 0x1E /* 0x1E Topology bits */
351#define LPB_mon_ltt 0x20 /* 0x20 */
352#define LPB_mon_lrt 0x22 /* 0x22 */
353#define LPB_num_pkts 0x24 /* 0x24 */
354#define LPB_add_packet_list 0x26 /* 0x26 Add packets to here */
355#define LPB_remove_packet_list 0x28 /* 0x28 Send packets from here */
356#define LPB_lrt_fail_chan 0x2A /* 0x2A Lrt's failure channel */
357#define LPB_ltt_fail_chan 0x2C /* 0x2C Ltt's failure channel */
358#define LPB_rup 0x2E /* 0x2E RUP structure for HOST to driver comms */
359#define LPB_link_rup 0x40 /* 0x40 RUP for the link (POLL, topology etc.) */
360#define LPB_attached_link 0x52 /* 0x52 Number of attached link */
361#define LPB_csum_errors 0x54 /* 0x54 csum errors */
362#define LPB_num_disconnects 0x56 /* 0x56 number of disconnects */
363#define LPB_num_sync_rcvd 0x58 /* 0x58 # sync's received */
364#define LPB_num_sync_rqst 0x5A /* 0x5A # sync requests */
365#define LPB_num_tx 0x5C /* 0x5C Num pkts sent */
366#define LPB_num_rx 0x5E /* 0x5E Num pkts received */
367#define LPB_module_attached 0x60 /* 0x60 Module tpyes of attached */
368#define LPB_led_timeout 0x62 /* 0x62 LED timeout */
369#define LPB_first_port 0x64 /* 0x64 First port to service */
370#define LPB_last_port 0x66 /* 0x66 Last port to service */
371#define sizeof_LPB 0x68 /* structure size = 0x68 */
372
373#define LINKS_PER_UNIT 4 /* number of links from a host */
374
375/*****************************************************************************
376******************************** *******************************
377******************************** FREE_LIST *******************************
378******************************** *******************************
379*****************************************************************************/
380
381/* Used to overlay packet headers when allocating/freeing packets from the free list */
382
383typedef struct _FREE_LIST
384{
385 _u16 next; /* 0x00 offset of next list item */
386 _u16 prev; /* 0x02 offset of previous list item */
387
388} FREE_LIST;
389
390/* Same thing again, but defined as offsets... */
391
392#define FL_next 0x00 /* 0x00 offset of next list item */
393#define FL_prev 0x02 /* 0x02 offset of previous list item */
394
395/*****************************************************************************
396********************************** ***********************************
397********************************** PKT ***********************************
398********************************** ***********************************
399*****************************************************************************/
400
401/* The PKT is the main unit of communication between Host Cards and RTAs across
402 the RIO network. */
403
404#define PKT_MAX_DATA_LEN 72 /* Size of packet data */
405
406typedef struct _PKT
407{
408 _u8 dest_unit; /* 0x00 Destination Unit Id */
409 _u8 dest_port; /* 0x01 Destination Port */
410 _u8 src_unit; /* 0x02 Source Unit Id */
411 _u8 src_port; /* 0x03 Source Port */
412 _u8 len; /* 0x04 Length (in bytes) of data field */
413 _u8 control; /* 0x05 */
414 _u8 data[PKT_MAX_DATA_LEN]; /* 0x06 Actual data */
415 _u16 csum; /* 0x4E C-SUM */
416
417} PKT;
418
419/* Same thing again, but defined as offsets... */
420
421#define PKT_dest_unit 0x00 /* 0x00 Destination Unit Id */
422#define PKT_dest_port 0x01 /* 0x01 Destination Port */
423#define PKT_src_unit 0x02 /* 0x02 Source Unit Id */
424#define PKT_src_port 0x03 /* 0x03 Source Port */
425#define PKT_len 0x04 /* 0x04 Length (in bytes) of data field */
426#define PKT_control 0x05 /* 0x05 */
427#define PKT_data 0x06 /* 0x06 Actual data */
428#define PKT_csum 0x4E /* 0x4E C-SUM */
429#define sizeof_PKT 0x50 /* structure size = 0x50 */
430
431/* PKT.len definitions... */
432#define PKT_CMD_BIT 0x80
433#define PKT_CMD_DATA 0x80
434#define PKT_LEN_MASK 0x7F
435
436/* PKT.control definitions... */
437#define PKT_ACK 0x40
438#define PKT_TGL 0x20
439#define DATA_WNDW 0x10
440#define PKT_TTL_MASK 0x0F
441#define MAX_TTL 0x0F
442
443/*****************************************************************************
444***************************** ****************************
445***************************** Control Packets ****************************
446***************************** ****************************
447*****************************************************************************/
448
449/* The following definitions and structures define the control packets sent
450 between the driver and RIO Ports, RTAs and Host Cards. */
451
452#define PRE_EMPTIVE 0x80 /* Pre-emptive command (sent via port's RUP) */
453
454/* "in-band" and "pre-emptive" port commands... */
455#define OPEN 0x00 /* Driver->RIO Open a port */
456#define CONFIG 0x01 /* Driver->RIO Configure a port */
457#define MOPEN 0x02 /* Driver->RIO Modem open (wait for DCD) */
458#define CLOSE 0x03 /* Driver->RIO Close a port */
459#define WFLUSH (0x04|PRE_EMPTIVE) /* Driver->RIO Write flush */
460#define RFLUSH (0x05|PRE_EMPTIVE) /* Driver->RIO Read flush */
461#define RESUME (0x06|PRE_EMPTIVE) /* Driver->RIO Behave as if XON received */
462#define SBREAK 0x07 /* Driver->RIO Start break */
463#define EBREAK 0x08 /* Driver->RIO End break */
464#define SUSPEND (0x09|PRE_EMPTIVE) /* Driver->RIO Behave as if XOFF received */
465#define FCLOSE (0x0A|PRE_EMPTIVE) /* Driver->RIO Force close */
466#define XPRINT 0x0B /* Driver->RIO Xprint packet */
467#define MBIS (0x0C|PRE_EMPTIVE) /* Driver->RIO Set modem lines */
468#define MBIC (0x0D|PRE_EMPTIVE) /* Driver->RIO Clear modem lines */
469#define MSET (0x0E|PRE_EMPTIVE) /* Driver->RIO Set modem lines */
470#define PCLOSE 0x0F /* Driver->RIO Pseudo close */
471#define MGET (0x10|PRE_EMPTIVE) /* Driver->RIO Force update of modem status */
472#define MEMDUMP (0x11|PRE_EMPTIVE) /* Driver->RIO DEBUG request for RTA memory */
473#define READ_REGISTER (0x12|PRE_EMPTIVE) /* Driver->RIO DEBUG read CD1400 register */
474
475/* Remote Unit Port (RUP) packet definitions... (specified in PKT.dest_unit and PKT.src_unit) */
476#define SYNC_RUP 0xFF /* Download internal */
477#define COMMAND_RUP 0xFE /* Command ack/status */
478#define ERROR_RUP 0xFD /* Download internal */
479#define POLL_RUP 0xFC /* Download internal */
480#define BOOT_RUP 0xFB /* Used to boot RTAs */
481#define ROUTE_RUP 0xFA /* Used to specify routing/topology */
482#define STATUS_RUP 0xF9 /* Not used */
483#define POWER_RUP 0xF8 /* Download internal */
484
485/* COMMAND_RUP definitions... */
486#define COMPLETE (0x20|PRE_EMPTIVE) /* RIO->Driver Command complete */
487#define BREAK_RECEIVED (0x21|PRE_EMPTIVE) /* RIO->Driver Break received */
488#define MODEM_STATUS (0x22|PRE_EMPTIVE) /* RIO->Driver Modem status change */
489
490/* BOOT_RUP definitions... */
491#define BOOT_REQUEST 0x00 /* RIO->Driver Request for boot */
492#define BOOT_ABORT 0x01 /* Driver->RIO Abort a boot */
493#define BOOT_SEQUENCE 0x02 /* Driver->RIO Packet with firmware details */
494#define BOOT_COMPLETED 0x03 /* RIO->Driver Boot completed */
495#define IFOAD 0x2F /* Driver->RIO Shutdown/Reboot RTA (Fall Over And Die) */
496#define IDENTIFY 0x30 /* Driver->RIO Identify RTA */
497#define ZOMBIE 0x31 /* Driver->RIO Shutdown/Flash LEDs */
498#define UFOAD 0x32 /* Driver->RIO Shutdown/Reboot neighbouring RTA */
499#define IWAIT 0x33 /* Driver->RIO Pause booting process */
500
501/* ROUTE_RUP definitions... */
502#define ROUTE_REQUEST 0x00 /* RIO->Driver Request an ID */
503#define ROUTE_FOAD 0x01 /* Driver->RIO Shutdown/reboot RTA */
504#define ROUTE_ALREADY 0x02 /* Driver->RIO Not used */
505#define ROUTE_USED 0x03 /* Driver->RIO Not used */
506#define ROUTE_ALLOCATE 0x04 /* Driver->RIO Allocate RTA RUP numbers */
507#define ROUTE_REQ_TOP 0x05 /* Driver->RIO Not used */
508#define ROUTE_TOPOLOGY 0x06 /* RIO->Driver Route/Topology status */
509
510/*****************************************************************************
511********************************** **********************************
512********************************** OPEN **********************************
513********************************** **********************************
514*****************************************************************************/
515
516/* (Driver->RIO,in-band)
517
518 Sent to open a port.
519 Structure of configuration info used with OPEN, CONFIG and MOPEN packets... */
520
521#define PKT_Cmd (PKT_Data+0) /* Command code */
522#define PKT_Cor1 (PKT_Data+1) /* Channel Option Register 1 */
523#define PKT_Cor2 (PKT_Data+2) /* Channel Option Register 2 */
524#define PKT_Cor4 (PKT_Data+3) /* Channel Option Register 4 */
525#define PKT_Cor5 (PKT_Data+4) /* Channel Option Register 5 */
526#define PKT_TxXon (PKT_Data+5) /* Transmit XON character */
527#define PKT_TxXoff (PKT_Data+6) /* Transmit XOFF character */
528#define PKT_RxXon (PKT_Data+7) /* Receive XON character */
529#define PKT_RxXoff (PKT_Data+8) /* Receive XOFF character */
530#define PKT_Lnext (PKT_Data+9) /* Lnext character */
531#define PKT_TxBaud (PKT_Data+10) /* Transmit baud rate */
532#define PKT_RxBaud (PKT_Data+11) /* Receive baud rate */
533
534/* COR1 definitions... */
535#define COR1_PARITY 0xE0 /* Parity mask */
536#define COR1_NONE 0x00 /* No parity */
537#define COR1_SPACE 0x20 /* Space parity */
538#define COR1_EVEN 0x40 /* Even parity */
539#define COR1_MARK 0xA0 /* Mark parity */
540#define COR1_ODD 0xC0 /* Odd parity */
541
542#define COR1_STOPBITS 0x0C /* Stop bits mask */
543#define COR1_STOP1 0x00 /* 1 stop bit */
544#define COR1_STOP1_5 0x04 /* 1.5 stop bits */
545#define COR1_STOP2 0x08 /* 2 stop bits */
546
547#define COR1_DATABITS 0x03 /* Data bits mask */
548#define COR1_DATA5 0x00 /* 5 data bits */
549#define COR1_DATA6 0x01 /* 6 data bits */
550#define COR1_DATA7 0x02 /* 7 data bits */
551#define COR1_DATA8 0x03 /* 8 data bits */
552
553/* COR2 definitions... */
554#define COR2_XON_TXFLOW 0x40 /* XON/XOFF Transmit Flow */
555#define COR2_XANY_TXFLOW 0xC0 /* XON/XANY Transmit Flow */
556#define COR2_HUPCL 0x20 /* Hang Up On Close */
557#define COR2_DSR_TXFLOW 0x08 /* DSR Transmit Flow Control */
558#define COR2_RTS_RXFLOW 0x04 /* RTS Receive Flow Control */
559#define COR2_CTS_TXFLOW 0x02 /* CTS Transmit Flow Control */
560#define COR2_XON_RXFLOW 0x01 /* XON/XOFF Receive Flow */
561
562/* COR4 definition... */
563#define COR4_IGNCR 0x80 /* Discard received CR */
564#define COR4_ICRNL 0x40 /* Map received CR -> NL */
565#define COR4_INLCR 0x20 /* Map received NL -> CR */
566#define COR4_IGNBRK 0x10 /* Ignore Received Break */
567#define COR4_NBRKINT 0x08 /* No interrupt on rx Break */
568#define COR4_IGNPAR 0x04 /* ignore rx parity error chars */
569#define COR4_PARMRK 0x02 /* Mark rx parity error chars */
570#define COR4_RAISEMOD 0x01 /* Raise modem lines on !0 baud */
571
572/* COR5 definitions... */
573#define COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */
574#define COR5_LNE 0x40 /* Enable LNEXT processing */
575#define COR5_CMOE 0x20 /* Match good & error characters */
576#define COR5_TAB3 0x10 /* TAB3 mode */
577#define COR5_TSTATE_ON 0x08 /* Enable tbusy/tstop monitoring */
578#define COR5_TSTATE_OFF 0x04 /* Disable tbusy/tstop monitoring */
579#define COR5_ONLCR 0x02 /* NL -> CR NL on output */
580#define COR5_OCRNL 0x01 /* CR -> NL on output */
581
582/* RxBaud and TxBaud definitions... */
583#define RIO_B0 0x00 /* RTS / DTR signals dropped */
584#define RIO_B50 0x01 /* 50 baud */
585#define RIO_B75 0x02 /* 75 baud */
586#define RIO_B110 0x03 /* 110 baud */
587#define RIO_B134 0x04 /* 134.5 baud */
588#define RIO_B150 0x05 /* 150 baud */
589#define RIO_B200 0x06 /* 200 baud */
590#define RIO_B300 0x07 /* 300 baud */
591#define RIO_B600 0x08 /* 600 baud */
592#define RIO_B1200 0x09 /* 1200 baud */
593#define RIO_B1800 0x0A /* 1800 baud */
594#define RIO_B2400 0x0B /* 2400 baud */
595#define RIO_B4800 0x0C /* 4800 baud */
596#define RIO_B9600 0x0D /* 9600 baud */
597#define RIO_B19200 0x0E /* 19200 baud */
598#define RIO_B38400 0x0F /* 38400 baud */
599#define RIO_B56000 0x10 /* 56000 baud */
600#define RIO_B57600 0x11 /* 57600 baud */
601#define RIO_B64000 0x12 /* 64000 baud */
602#define RIO_B115200 0x13 /* 115200 baud */
603#define RIO_B2000 0x14 /* 2000 baud */
604
605/*****************************************************************************
606********************************* *********************************
607********************************* CONFIG *********************************
608********************************* *********************************
609*****************************************************************************/
610
611/* (Driver->RIO,in-band)
612
613 CONFIG is sent from the driver to configure an already opened port.
614 Packet structure is same as OPEN. */
615
616/*****************************************************************************
617********************************* **********************************
618********************************* MOPEN **********************************
619********************************* **********************************
620*****************************************************************************/
621
622/* (Driver->RIO,in-band)
623
624 MOPEN is sent from the driver to open a port attached to a modem. (in-band)
625 Packet structure is same as OPEN. */
626
627/*****************************************************************************
628********************************* **********************************
629********************************* CLOSE **********************************
630********************************* **********************************
631*****************************************************************************/
632
633/* (Driver->RIO,in-band)
634
635 CLOSE is sent from the driver to close a previously opened port.
636 No parameters.
637 */
638#if 0
639#define PKT_Cmd (PKT_Data+0) /* Command code */
640#endif
641/*****************************************************************************
642********************************* *********************************
643********************************* WFLUSH *********************************
644********************************* *********************************
645*****************************************************************************/
646
647/* (Driver->RIO,pre-emptive)
648
649 WFLUSH is sent pre-emptively from the driver to flush the write buffers and
650 packets of a port. (pre-emptive)
651
652 WFLUSH is also sent in-band from the driver to a port as a marker to end
653 write flushing previously started by a pre-emptive WFLUSH packet. (in-band)
654 */
655#if 0
656#define PKT_Cmd (PKT_Data+0) /* Command code */
657#endif
658#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
659
660/*****************************************************************************
661********************************* *********************************
662********************************* RFLUSH *********************************
663********************************* *********************************
664*****************************************************************************/
665
666/* (Driver->RIO,pre-emptive)
667
668 RFLUSH is sent pre-emptively from the driver to flush the read buffers and
669 packets of a port.
670 */
671#if 0
672#define PKT_Cmd (PKT_Data+0) /* Command code */
673#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
674#endif
675
676/*****************************************************************************
677********************************* *********************************
678********************************* RESUME *********************************
679********************************* *********************************
680*****************************************************************************/
681
682/* (Driver->RIO,pre-emptive)
683
684 RESUME is sent pre-emptively from the driver to cause a port to resume
685 transmission of data if blocked by XOFF. (as if XON had been received)
686 */
687#if 0
688#define PKT_Cmd (PKT_Data+0) /* Command code */
689#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
690#endif
691
692/*****************************************************************************
693********************************* *********************************
694********************************* SBREAK *********************************
695********************************* *********************************
696*****************************************************************************/
697
698/* (Driver->RIO,in-band)
699
700 SBREAK is sent in-band from the driver to a port to suspend data and start
701 break signal transmission.
702
703 If the break delay is 0, the break signal will be acknowledged with a
704 RUP_COMMAND, COMPLETE packet and continue until an EBREAK packet is received.
705
706 Otherwise, there is no acknowledgement and the break signal will last for the
707 specified number of mS.
708 */
709#if 0
710#define PKT_Cmd (PKT_Data+0) /* Command code */
711#endif
712#define PKT_BreakDelay (PKT_Data+1) /* Break delay in mS */
713
714/*****************************************************************************
715********************************* *********************************
716********************************* EBREAK *********************************
717********************************* *********************************
718*****************************************************************************/
719
720/* (Driver->RIO,in-band)
721
722 EBREAK is sent in-band from the driver to a port to stop transmission of a
723 break signal.
724
725 No parameters. */
726
727/*****************************************************************************
728********************************* ********************************
729********************************* SUSPEND ********************************
730********************************* ********************************
731*****************************************************************************/
732
733/* (Driver->RIO,pre-emptive)
734
735 SUSPEND is sent pre-emptively from the driver to cause a port to suspend
736 transmission of data. (as if XOFF had been received)
737 */
738#if 0
739#define PKT_Cmd (PKT_Data+0) /* Command code */
740#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
741#endif
742
743/*****************************************************************************
744********************************* *********************************
745********************************* FCLOSE *********************************
746********************************* *********************************
747*****************************************************************************/
748
749/* (Driver->RIO,pre-emptive)
750
751 FCLOSE is sent pre-emptively from the driver to force close a port.
752 A force close flushes receive and transmit queues, and also lowers all output
753 modem signals if the COR5_HUPCL (Hang Up On Close) flag is set.
754 */
755#if 0
756#define PKT_Cmd (PKT_Data+0) /* Command code */
757#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
758#endif
759
760/*****************************************************************************
761********************************* *********************************
762********************************* XPRINT *********************************
763********************************* *********************************
764*****************************************************************************/
765
766/* (Driver->RIO,in-band)
767
768 XPRINT is sent as a normal I/O data packet except that the PKT_CMD_BIT of
769 the "len" field is set, and the first "data" byte is XPRINT.
770
771 The I/O data in the XPRINT packet will contain the following:
772 - Transparent Print Start Sequence
773 - Transparent Print Data
774 - Transparent Print Stop Sequence.
775 */
776#if 0
777#define PKT_Cmd (PKT_Data+0) /* Command code */
778#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
779#endif
780
781/*****************************************************************************
782********************************** **********************************
783********************************** MBIS **********************************
784********************************** **********************************
785*****************************************************************************/
786
787/* (Driver->RIO,pre-emptive)
788
789 MBIS is sent pre-emptively from the driver to set a port's modem signals.
790 */
791#if 0
792#define PKT_Cmd (PKT_Data+0) /* Command code */
793#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
794#endif
795#define PKT_ModemSet (PKT_Data+4) /* Modem set signals mask */
796
797/* ModemSet definitions... */
798#define MBIS_RTS 0x01 /* RTS modem signal */
799#define MBIS_DTR 0x02 /* DTR modem signal */
800
801/*****************************************************************************
802********************************** **********************************
803********************************** MBIC **********************************
804********************************** **********************************
805*****************************************************************************/
806
807/* (Driver->RIO,pre-emptive)
808
809 MBIC is sent pre-emptively from the driver to clear a port's modem signals.
810 */
811#if 0
812#define PKT_Cmd (PKT_Data+0) /* Command code */
813#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
814#endif
815
816#define PKT_ModemClear (PKT_Data+4) /* Modem clear signals mask */
817
818/* ModemClear definitions... */
819#define MBIC_RTS 0x01 /* RTS modem signal */
820#define MBIC_DTR 0x02 /* DTR modem signal */
821
822/*****************************************************************************
823********************************** **********************************
824********************************** MSET **********************************
825********************************** **********************************
826*****************************************************************************/
827
828/* (Driver->RIO,pre-emptive)
829
830 MSET is sent pre-emptively from the driver to set/clear a port's modem signals. */
831#if 0
832#define PKT_Cmd (PKT_Data+0) /* Command code */
833#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
834#endif
835
836#define PKT_ModemSet (PKT_Data+4) /* Modem set signals mask */
837
838/* ModemSet definitions... */
839#define MSET_RTS 0x01 /* RTS modem signal */
840#define MSET_DTR 0x02 /* DTR modem signal */
841
842/*****************************************************************************
843********************************* *********************************
844********************************* PCLOSE *********************************
845********************************* *********************************
846*****************************************************************************/
847
848/* (Driver->RIO,in-band)
849
850 PCLOSE is sent from the driver to pseudo close a previously opened port.
851
852 The port will close when all data has been sent/received, however, the
853 port's transmit / receive and modem signals will be left enabled and the
854 port marked internally as Pseudo Closed. */
855
856#define PKT_Cmd (PKT_Data+0) /* Command code */
857
858/*****************************************************************************
859********************************** **********************************
860********************************** MGET **********************************
861********************************** **********************************
862*****************************************************************************/
863
864/* (Driver->RIO,pre-emptive)
865
866 MGET is sent pre-emptively from the driver to request the port's current modem signals. */
867
868#define PKT_Cmd (PKT_Data+0) /* Command code */
869#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
870
871/*****************************************************************************
872********************************* ********************************
873********************************* MEMDUMP ********************************
874********************************* ********************************
875*****************************************************************************/
876
877/* (Driver->RIO,pre-emptive)
878
879 MEMDUMP is sent pre-emptively from the driver to request a dump of 32 bytes
880 of the specified port's RTA address space.
881 */
882#if 0
883#define PKT_Cmd (PKT_Data+0) /* Command code */
884#endif
885#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
886#define PKT_SubCmd (PKT_Data+5) /* Sub Command */
887#define PKT_Address (PKT_Data+6) /* Requested address */
888
889/*****************************************************************************
890****************************** *****************************
891****************************** READ_REGISTER *****************************
892****************************** *****************************
893*****************************************************************************/
894
895/* (Driver->RIO,pre-emptive)
896
897 READ_REGISTER is sent pre-emptively from the driver to request the contents
898 of the CD1400 register specified in address.
899 */
900#if 0
901#define PKT_Cmd (PKT_Data+0) /* Command code */
902#endif
903#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
904#define PKT_SubCmd (PKT_Data+5) /* Sub Command */
905#define PKT_Address (PKT_Data+6) /* Requested address */
906
907/*****************************************************************************
908************************ **************************
909************************ COMMAND_RUP - COMPLETE **************************
910************************ **************************
911*****************************************************************************/
912
913/* (RIO->Driver,pre-emptive)
914
915 COMMAND_RUP - COMPLETE is sent in response to all port I/O control command
916 packets, except MEMDUMP and READ_REGISTER.
917 */
918#if 0
919#define PKT_Cmd (PKT_Data+0) /* Command code */
920#endif
921#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
922#define PKT_Cmd2 (PKT_Data+2) /* Command code copy */
923#define PKT_ModemStatus (PKT_Data+3) /* Modem signal status */
924#define PKT_PortStatus (PKT_Data+4) /* Port signal status */
925#define PKT_SubCmd (PKT_Data+5) /* Sub Command */
926
927/* ModemStatus definitions... */
928#define MODEM_DSR 0x80 /* Data Set Ready modem state */
929#define MODEM_CTS 0x40 /* Clear To Send modem state */
930#define MODEM_RI 0x20 /* Ring Indicate modem state */
931#define MODEM_CD 0x10 /* Carrier Detect modem state */
932#define MODEM_TSTOP 0x08 /* Transmit Stopped state */
933#define MODEM_TEMPTY 0x04 /* Transmit Empty state */
934#define MODEM_DTR 0x02 /* DTR modem output state */
935#define MODEM_RTS 0x01 /* RTS modem output state */
936
937/* PortStatus definitions... */
938#define PORT_ISOPEN 0x01 /* Port open ? */
939#define PORT_HUPCL 0x02 /* Hangup on close? */
940#define PORT_MOPENPEND 0x04 /* Modem open pending */
941#define PORT_ISPARALLEL 0x08 /* Parallel port */
942#define PORT_BREAK 0x10 /* Port on break */
943#define PORT_STATUSPEND 0020 /* Status packet pending */
944#define PORT_BREAKPEND 0x40 /* Break packet pending */
945#define PORT_MODEMPEND 0x80 /* Modem status packet pending */
946
947/*****************************************************************************
948************************ **************************
949************************ COMMAND_RUP - COMPLETE **************************
950************************ **************************
951*****************************************************************************/
952
953/* (RIO->Driver,pre-emptive)
954
955 COMMAND_RUP - COMPLETE is sent in response to all port I/O control command
956 packets, except MEMDUMP and READ_REGISTER.
957 */
958#if 0
959#define PKT_Cmd (PKT_Data+0) /* Command code */
960#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
961#define PKT_Cmd2 (PKT_Data+2) /* Command code copy */
962#endif
963#define PKT_ModemStatus (PKT_Data+3) /* Modem signal status */
964#define PKT_PortStatus (PKT_Data+4) /* Port signal status */
965#if 0
966#define PKT_SubCmd (PKT_Data+5) /* Sub Command */
967#endif
968
969/* ModemStatus definitions... */
970#define MODEM_DSR 0x80 /* Data Set Ready modem state */
971#define MODEM_CTS 0x40 /* Clear To Send modem state */
972#define MODEM_RI 0x20 /* Ring Indicate modem state */
973#define MODEM_CD 0x10 /* Carrier Detect modem state */
974#define MODEM_TSTOP 0x08 /* Transmit Stopped state */
975#define MODEM_TEMPTY 0x04 /* Transmit Empty state */
976#define MODEM_DTR 0x02 /* DTR modem output state */
977#define MODEM_RTS 0x01 /* RTS modem output state */
978
979/* PortStatus definitions... */
980#define PORT_ISOPEN 0x01 /* Port open ? */
981#define PORT_HUPCL 0x02 /* Hangup on close? */
982#define PORT_MOPENPEND 0x04 /* Modem open pending */
983#define PORT_ISPARALLEL 0x08 /* Parallel port */
984#define PORT_BREAK 0x10 /* Port on break */
985#define PORT_STATUSPEND 0020 /* Status packet pending */
986#define PORT_BREAKPEND 0x40 /* Break packet pending */
987#define PORT_MODEMPEND 0x80 /* Modem status packet pending */
988
989/*****************************************************************************
990******************** ********************
991******************** COMMAND_RUP - COMPLETE - MEMDUMP ********************
992******************** ********************
993*****************************************************************************/
994
995/* (RIO->Driver,pre-emptive)
996
997 COMMAND_RUP - COMPLETE - MEMDUMP is sent as an acknowledgement for a MEMDUMP
998 port I/O control command packet.
999 */
1000#if 0
1001#define PKT_Cmd (PKT_Data+0) /* Command code */
1002#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
1003#define PKT_Cmd2 (PKT_Data+2) /* Command code copy */
1004#define PKT_ModemStatus (PKT_Data+3) /* Modem signal status */
1005#define PKT_PortStatus (PKT_Data+4) /* Port signal status */
1006#define PKT_SubCmd (PKT_Data+5) /* Sub Command */
1007#define PKT_Address (PKT_Data+6) /* Requested address */
1008#endif
1009#define PKT_Dump (PKT_Data+8) /* 32bytes of requested dump data */
1010
1011/*****************************************************************************
1012***************** *****************
1013***************** COMMAND_RUP - COMPLETE - READ_REGISTER *****************
1014***************** *****************
1015*****************************************************************************/
1016
1017/* (RIO->Driver,pre-emptive)
1018
1019 COMMAND_RUP - COMPLETE - READ_REGISTER is sent as an acknowledgement for a
1020 READ_REGISTER port I/O control command packet.
1021 */
1022#if 0
1023#define PKT_Cmd (PKT_Data+0) /*Command code */
1024#define PKT_PhbNum (PKT_Data+1) /*Port number wrt RTA */
1025#define PKT_Cmd2 (PKT_Data+2) /* Command code copy */
1026#endif
1027#define PKT_RegisterValue (PKT_Data+3) /* Modem signal status */
1028#if 0
1029#define PKT_PortStatus (PKT_Data+4) /* Port signal status */
1030#define PKT_SubCmd (PKT_Data+5) /* Sub Command */
1031#endif
1032
1033/*****************************************************************************
1034********************* ***********************
1035********************* COMMAND_RUP - BREAK_RECEIVED ***********************
1036********************* ***********************
1037*****************************************************************************/
1038
1039/* (RIO->Driver,pre-emptive)
1040
1041 COMMAND_RUP - BREAK_RECEIVED packets are sent when the port detects a receive BREAK signal.
1042 */
1043#if 0
1044#define PKT_Cmd (PKT_Data+0) /* Command code */
1045#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
1046#define PKT_Cmd2 (PKT_Data+2) /* Command code copy */
1047#endif
1048
1049/*****************************************************************************
1050********************* *************************
1051********************* COMMAND_RUP - MODEM_STATUS *************************
1052********************* *************************
1053*****************************************************************************/
1054
1055/* (RIO->Driver,pre-emptive)
1056
1057 COMMAND_RUP - MODEM_STATUS packets are sent whenever the port detects a
1058 change in the input modem signal states.
1059
1060 */
1061#if 0
1062#define PKT_Cmd (PKT_Data+0) /* Command code */
1063#define PKT_PhbNum (PKT_Data+1) /* Port number wrt RTA */
1064#define PKT_Cmd2 (PKT_Data+2) /* Command code copy */
1065#define PKT_ModemStatus (PKT_Data+3) /* Modem signal status */
1066#endif
1067
1068/*****************************************************************************
1069************************ *************************
1070************************ BOOT_RUP - BOOT_REQUEST *************************
1071************************ *************************
1072*****************************************************************************/
1073
1074/* (RIO->Driver,pre-emptive)
1075
1076 BOOT_RUP - BOOT_REQUEST packets are sent to the Driver from RIO to request
1077 firmware code to load onto attached RTAs.
1078 */
1079#if 0
1080#define PKT_Cmd (PKT_Data+0) /* Command code */
1081#endif
1082
1083/*****************************************************************************
1084************************ ************************
1085************************ BOOT_RUP - BOOT_SEQUENCE ************************
1086************************ ************************
1087*****************************************************************************/
1088
1089/* (Driver->RIO,pre-emptive)
1090
1091 BOOT_RUP - BOOT_SEQUENCE packets are sent from the Driver to RIO in response
1092 to a BOOT_RUP - BOOT_REQUEST packet.
1093 */
1094#if 0
1095#define PKT_Cmd (PKT_Data+0) /* Command code */
1096#endif
1097#define PKT_NumPackets (PKT_Data+2) /* Packets required to load firmware */
1098#define PKT_LoadBase (PKT_Data+4) /* RTA firmware load address */
1099#define PKT_CodeSize (PKT_Data+6) /* Size of firmware in bytes */
1100#define PKT_CmdString (PKT_Data+8) /* Command string */
1101
1102/*****************************************************************************
1103************************ ***********************
1104************************ BOOT_RUP - BOOT_COMPLETED ***********************
1105************************ ***********************
1106*****************************************************************************/
1107
1108/* (RIO->Driver,pre-emptive)
1109
1110 BOOT_RUP - BOOT_COMPLETE is sent to the Driver from RIO when downloading of
1111 RTA firmware has completed.
1112 */
1113#if 0
1114#define PKT_Cmd (PKT_Data+0) /* Command code */
1115#endif
1116#define PKT_LinkNumber (PKT_Data+1) /* Link number RTA booted on */
1117#define PKT_SerialNumber (PKT_Data+2) /* 4 byte serial number */
1118
1119/*****************************************************************************
1120************************ ***********************
1121************************ BOOT_RUP - Packet Request ***********************
1122************************ ***********************
1123*****************************************************************************/
1124
1125/* (RIO->Driver,pre-emptive)
1126
1127 BOOT_RUP packet without the PKT_CMD_BIT set in the PKT->len field is sent
1128 from RIO to the Driver as a request for a firmware boot packet. */
1129
1130#define PKT_SequenceNumber (PKT_Data+0) /* Packet sequence number */
1131
1132/*****************************************************************************
1133*********************** ***********************
1134*********************** BOOT_RUP - Packet Response ***********************
1135*********************** ***********************
1136*****************************************************************************/
1137
1138/* (Driver->RIO,pre-emptive)
1139
1140 In response to a BOOT_RUP boot packet request, the driver fills out the response
1141 packet with the 70 bytes of the requested sequence.
1142 */
1143#if 0
1144#define PKT_SequenceNumber (PKT_Data+0) /* Packet sequence number */
1145#endif
1146#define PKT_FirmwarePacket (PKT_Data+2) /* Firmware packet */
1147
1148/*****************************************************************************
1149**************************** ****************************
1150**************************** BOOT_RUP - IFOAD ****************************
1151**************************** ****************************
1152*****************************************************************************/
1153
1154/* (Driver->RIO,pre-emptive)
1155
1156 BOOT_RUP - IFOAD packets are sent from the Driver to an RTA to cause the
1157 RTA to shut down and reboot.
1158 */
1159#if 0
1160#define PKT_Cmd (PKT_Data+0) /* Command code */
1161#endif
1162#define PKT_IfoadId1 (PKT_Data+2) /* IFOAD Id 1 */
1163#define PKT_IfoadId2 (PKT_Data+3) /* IFOAD Id 2 */
1164
1165#define IFOADID1 0xAD
1166#define IFOADID2 0xF0
1167
1168/*****************************************************************************
1169************************** ***************************
1170************************** BOOT_RUP - IDENTIFY ***************************
1171************************** ***************************
1172*****************************************************************************/
1173
1174/* (Driver->RIO,pre-emptive)
1175
1176 BOOT_RUP - IDENTIFY packets are sent from the Driver to an RTA to cause the
1177 RTA to flash its LEDs for a period of time.
1178 */
1179#if 0
1180#define PKT_Cmd (PKT_Data+0) /* Command code */
1181#endif
1182#define PKT_IdentifyId (PKT_Data+2) /* defines pattern to flash */
1183
1184/*****************************************************************************
1185**************************** ***************************
1186**************************** BOOT_RUP - ZOMBIE ***************************
1187**************************** ***************************
1188*****************************************************************************/
1189
1190/* (Driver->RIO,pre-emptive)
1191
1192 BOOT_RUP - ZOMBIE packets are sent from the Driver to an RTA to cause the
1193 RTA to shut down and flash it's LEDs.
1194 */
1195#if 0
1196#define PKT_Cmd (PKT_Data+0) /* Command code */
1197#endif
1198#define PKT_ZombieId1 (PKT_Data+2) /* ZOMBIE Id 1 */
1199#define PKT_ZombieId2 (PKT_Data+3) /* ZOMBIE Id 2 */
1200
1201#define ZOMBIEID1 0x52
1202#define ZOMBIEID2 0x21
1203
1204/*****************************************************************************
1205**************************** ****************************
1206**************************** BOOT_RUP - UFOAD ****************************
1207**************************** ****************************
1208*****************************************************************************/
1209
1210/* (Driver->RIO,pre-emptive)
1211
1212 BOOT_RUP - UFOAD packets are sent from the Driver to an RTA to cause the RTA
1213 to ask it's neighbouring RTA to shut down and reboot.
1214 */
1215#if 0
1216#define PKT_Cmd (PKT_Data+0) /* Command code */
1217#define PKT_LinkNumber (PKT_Data+1) /* Link number of RTA to UFOAD */
1218#endif
1219#define PKT_UfoadId1 (PKT_Data+2) /* UFOAD Id 1 */
1220#define PKT_UfoadId2 (PKT_Data+3) /* UFOAD Id 2 */
1221
1222#define UFOADID1 0x1E
1223#define UFOADID2 0x0D
1224
1225/*****************************************************************************
1226**************************** ****************************
1227**************************** BOOT_RUP - IWAIT ****************************
1228**************************** ****************************
1229*****************************************************************************/
1230
1231/* (Driver->RIO,pre-emptive)
1232
1233 BOOT_RUP - IWAIT packets are sent from the Driver to an RTA to cause the RTA
1234 to pause booting on the specified link for 30 seconds.
1235 */
1236#if 0
1237#define PKT_Cmd (PKT_Data+0) /* Command code */
1238#define PKT_LinkNumber (PKT_Data+1) /* Link number of RTA to UFOAD */
1239#endif
1240#define PKT_IwaitId1 (PKT_Data+2) /* IWAIT Id 1 */
1241#define PKT_IwaitId2 (PKT_Data+3) /* IWAIT Id 2 */
1242
1243#define IWAITID1 0xDE
1244#define IWAITID2 0xB1
1245
1246/*****************************************************************************
1247************************ ***********************
1248************************ ROUTE_RUP - ROUTE_REQUEST ***********************
1249************************ ***********************
1250*****************************************************************************/
1251
1252/* (RIO->Driver,pre-emptive)
1253
1254 ROUTE_RUP - ROUTE_REQUEST packets are sent from a newly booted or connected
1255 RTA to a Driver to request an ID (RUP or unit number).
1256 */
1257#if 0
1258#define PKT_Cmd (PKT_Data+0) /* Command code */
1259#endif
1260#define PKT_SerialNumber (PKT_Data+2) /* 4 byte serial number */
1261#define PKT_ModuleTypes (PKT_Data+6) /* RTA Module types */
1262
1263/* ModuleTypes definitions... */
1264#define MOD_BLANK 0x0F /* Blank plate attached */
1265#define MOD_RS232DB25 0x00 /* RS232 DB25 connector */
1266#define MOD_RS232RJ45 0x01 /* RS232 RJ45 connector */
1267#define MOD_RS422DB25 0x02 /* RS422 DB25 connector */
1268#define MOD_RS485DB25 0x03 /* RS485 DB25 connector */
1269#define MOD_PARALLEL 0x04 /* Centronics parallel */
1270
1271#define MOD2 0x08 /* Set to indicate Rev2 module */
1272
1273/*****************************************************************************
1274************************* *************************
1275************************* ROUTE_RUP - ROUTE_FOAD *************************
1276************************* *************************
1277*****************************************************************************/
1278
1279/* (Driver->RIO,pre-emptive)
1280
1281 ROUTE_RUP - ROUTE_FOAD packet is sent as a response to a ROUTE_RUP - ROUTE_REQUEST
1282 packet to cause the RTA to "Fall Over And Die"., i.e. shutdown and reboot.
1283 */
1284#if 0
1285#define PKT_Cmd (PKT_Data+0) /* Command code */
1286#endif
1287#define PKT_RouteCmdString (PKT_Data+2) /* Command string */
1288
1289/*****************************************************************************
1290*********************** ***********************
1291*********************** ROUTE_RUP - ROUTE_ALLOCATE ***********************
1292*********************** ***********************
1293*****************************************************************************/
1294
1295/* (Driver->RIO,pre-emptive)
1296
1297 ROUTE_RUP - ROUTE_ALLOCATE packet is sent as a response to a ROUTE_RUP - ROUTE_REQUEST
1298 packet to allocate the RTA's Id number (RUP number 1..16)
1299 */
1300#if 0
1301#define PKT_Cmd (PKT_Data+0) /* Command code */
1302#endif
1303#define PKT_IdNum (PKT_Data+1) /* RUP number for ports 1..8 */
1304#if 0
1305#define PKT_RouteCmdString (PKT_Data+2) /* Command string */
1306#endif
1307#define PKT_IdNum2 (PKT_Data+0x17) /* RUP number for ports 9..16 */
1308
1309/*****************************************************************************
1310*********************** ***********************
1311*********************** ROUTE_RUP - ROUTE_TOPOLOGY ***********************
1312*********************** ***********************
1313*****************************************************************************/
1314
1315/* (RIO->Driver,pre-emptive)
1316
1317 ROUTE_RUP - ROUTE_TOPOLOGY packet is sent to inform the driver of an RTA's
1318 current link status.
1319 */
1320#if 0
1321#define PKT_Cmd (PKT_Data+0) /* Command code */
1322#endif
1323#define PKT_Link1Rup (PKT_Data+2) /* Link 1 RUP number */
1324#define PKT_Link1Link (PKT_Data+3) /* Link 1 link number */
1325#define PKT_Link2Rup (PKT_Data+4) /* Link 2 RUP number */
1326#define PKT_Link2Link (PKT_Data+5) /* Link 2 link number */
1327#define PKT_Link3Rup (PKT_Data+6) /* Link 3 RUP number */
1328#define PKT_Link3Link (PKT_Data+7) /* Link 3 link number */
1329#define PKT_Link4Rup (PKT_Data+8) /* Link 4 RUP number */
1330#define PKT_Link4Link (PKT_Data+9) /* Link 4 link number */
1331#define PKT_RtaVpdProm (PKT_Data+10) /* 32 bytes of RTA VPD PROM Contents */
1332
1333#endif /* _sxwinif_h */
1334
1335/* End of RIOWINIF.H */
diff --git a/drivers/char/rio/riscos.h b/drivers/char/rio/riscos.h
new file mode 100644
index 000000000000..7685cc1d9e7b
--- /dev/null
+++ b/drivers/char/rio/riscos.h
@@ -0,0 +1,63 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : riscos.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:19
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)riscos.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_riscos_h__
34#define __rio_riscos_h__
35
36#ifdef SCCS_LABELS
37static char *_riscos_h_sccs_ = "@(#)riscos.h 1.2";
38#endif
39
40/*
41** This module used to define all those little itsy bits required for RISC/OS
42** now it's full of null macros.
43*/
44
45/*
46** RBYTE reads a byte from a location.
47** RWORD reads a word from a location.
48** WBYTE writes a byte to a location.
49** WWORD writes a word to a location.
50** RINDW reads a word through a pointer.
51** WINDW writes a word through a pointer.
52** RIOSWAB swaps the two bytes of a word, if needed.
53*/
54
55#define RIOSWAB(N) (N)
56#define WBYTE(A,V) (A)=(uchar)(V)
57#define WWORD(A,V) (A)=(ushort)(V)
58#define RBYTE(A) (uchar)(A)
59#define RWORD(A) (ushort)(A)
60#define RINDW(A) (*(ushort *)(A))
61#define WINDW(A,V) (*(ushort *)(A)=(ushort)(V))
62
63#endif /* __rio_riscos_h__ */
diff --git a/drivers/char/rio/rom.h b/drivers/char/rio/rom.h
new file mode 100644
index 000000000000..ee79b8e5b972
--- /dev/null
+++ b/drivers/char/rio/rom.h
@@ -0,0 +1,64 @@
1/****************************************************************************
2 ******* *******
3 ******* R O M
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _rom_h
38#define _rom_h 1
39
40#ifndef lint
41#ifdef SCCS
42static char *_rio_rom_h_sccs = "@(#)rom.h 1.1" ;
43#endif
44#endif
45
46typedef struct ROM ROM ;
47struct ROM {
48 u_short slx ;
49 char pcb_letter_rev ;
50 char pcb_number_rev ;
51 char serial[4] ;
52 char year ;
53 char week ;
54 } ;
55
56#endif
57
58#define HOST_ROM (ROM *) 0x7c00
59#define RTA_ROM (ROM *) 0x7801
60#define ROM_LENGTH 0x20
61
62/*********** end of file ***********/
63
64
diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h
new file mode 100644
index 000000000000..c42dbb971718
--- /dev/null
+++ b/drivers/char/rio/route.h
@@ -0,0 +1,108 @@
1/****************************************************************************
2 ******* *******
3 ******* R O U T E H E A D E R
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra / Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _route_h
38#define _route_h
39
40#ifdef SCCS_LABELS
41#ifndef lint
42/* static char *_rio_route_h_sccs = "@(#)route.h 1.3"; */
43#endif
44#endif
45
46#define MAX_LINKS 4
47#define MAX_NODES 17 /* Maximum nodes in a subnet */
48#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for
49 1 bit per node */
50#define ROUTE_DATA_SIZE (NODE_BYTES + 2) /* Number of bytes for complete
51 info about cost etc. */
52#define ROUTES_PER_PACKET ((PKT_MAX_DATA_LEN -2)/ ROUTE_DATA_SIZE)
53 /* Number of nodes we can squeeze
54 into one packet */
55#define MAX_TOPOLOGY_PACKETS (MAX_NODES / ROUTES_PER_PACKET + 1)
56/************************************************
57 * Define the types of command for the ROUTE RUP.
58 ************************************************/
59#define ROUTE_REQUEST 0 /* Request an ID */
60#define ROUTE_FOAD 1 /* Kill the RTA */
61#define ROUTE_ALREADY 2 /* ID given already */
62#define ROUTE_USED 3 /* All ID's used */
63#define ROUTE_ALLOCATE 4 /* Here it is */
64#define ROUTE_REQ_TOP 5 /* I bet you didn't expect....
65 the Topological Inquisition */
66#define ROUTE_TOPOLOGY 6 /* Topology request answered FD */
67/*******************************************************************
68 * Define the Route Map Structure
69 *
70 * The route map gives a pointer to a Link Structure to use.
71 * This allows Disconnected Links to be checked quickly
72 ******************************************************************/
73typedef struct COST_ROUTE COST_ROUTE;
74struct COST_ROUTE {
75 unsigned char cost; /* Cost down this link */
76 unsigned char route[NODE_BYTES]; /* Nodes thorough this route */
77 } ;
78
79typedef struct ROUTE_STR ROUTE_STR ;
80struct ROUTE_STR {
81 COST_ROUTE cost_route[MAX_LINKS];
82 /* cost / route for this link */
83 ushort favoured; /* favoured link */
84 } ;
85
86
87#define NO_LINK (short) 5 /* Link unattached */
88#define ROUTE_NO_ID (short) 100 /* No Id */
89#define ROUTE_DISCONNECT (ushort) 0xff /* Not connected */
90#define ROUTE_INTERCONNECT (ushort) 0x40 /* Sub-net interconnect */
91
92
93#define SYNC_RUP (ushort) 255
94#define COMMAND_RUP (ushort) 254
95#define ERROR_RUP (ushort) 253
96#define POLL_RUP (ushort) 252
97#define BOOT_RUP (ushort) 251
98#define ROUTE_RUP (ushort) 250
99#define STATUS_RUP (ushort) 249
100#define POWER_RUP (ushort) 248
101
102#define HIGHEST_RUP (ushort) 255 /* Set to Top one */
103#define LOWEST_RUP (ushort) 248 /* Set to bottom one */
104
105#endif
106
107/*********** end of file ***********/
108
diff --git a/drivers/char/rio/rtahw.h b/drivers/char/rio/rtahw.h
new file mode 100644
index 000000000000..06860118cbc5
--- /dev/null
+++ b/drivers/char/rio/rtahw.h
@@ -0,0 +1,75 @@
1
2/****************************************************************************
3 ******* *******
4 ******* R T A H A R D W A R E
5 ******* *******
6 ****************************************************************************
7
8 Author : Ian Nandhra
9 Date :
10
11 *
12 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 Version : 0.01
29
30
31 Mods
32 ----------------------------------------------------------------------------
33 Date By Description
34 ----------------------------------------------------------------------------
35
36 ***************************************************************************/
37
38#ifndef lint
39#ifdef SCCS_LABELS
40static char *_rio_rtahw_h_sccs = "@(#)rtahw.h 1.5" ;
41#endif
42#endif
43
44#define WATCHDOG_ADDR ((unsigned short *)0x7a00)
45#define RTA_LED_ADDR ((unsigned short *)0x7c00)
46#define SERIALNUM_ADDR ((unsigned char *)0x7809)
47#define LATCH_ADDR ((unsigned char *)0x7800)
48
49/*
50** Here we define where the cd1400 chips are in memory.
51*/
52#define CD1400_ONE_ADDR (0x7300)
53#define CD1400_TWO_ADDR (0x7200)
54#define CD1400_THREE_ADDR (0x7100)
55#define CD1400_FOUR_ADDR (0x7000)
56
57/*
58** Define the different types of modules we can have
59*/
60enum module {
61 MOD_BLANK = 0x0f, /* Blank plate attached */
62 MOD_RS232DB25 = 0x00, /* RS232 DB25 connector */
63 MOD_RS232RJ45 = 0x01, /* RS232 RJ45 connector */
64 MOD_RS422DB25 = 0x02, /* RS422 DB25 connector */
65 MOD_RS485DB25 = 0x03, /* RS485 DB25 connector */
66 MOD_PARALLEL = 0x04 /* Centronics parallel */
67};
68
69#define TYPE_HOST 0
70#define TYPE_RTA8 1
71#define TYPE_RTA16 2
72
73#define WATCH_DOG WATCHDOG_ADDR
74
75/*********** end of file ***********/
diff --git a/drivers/char/rio/rup.h b/drivers/char/rio/rup.h
new file mode 100644
index 000000000000..b9d2bc03d14b
--- /dev/null
+++ b/drivers/char/rio/rup.h
@@ -0,0 +1,82 @@
1/****************************************************************************
2 ******* *******
3 ******* R U P S T R U C T U R E
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _rup_h
38#define _rup_h 1
39
40#ifdef SCCS_LABELS
41#ifndef lint
42/* static char *_rio_rup_h_sccs = "@(#)rup.h 1.5"; */
43#endif
44#endif
45
46#if defined( HOST ) || defined( INKERNEL )
47#define MAX_RUP ((short) 16)
48#endif
49#ifdef RTA
50#define MAX_RUP ((short) 1)
51#endif
52
53#define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */
54
55/*************************************************
56 * Define all the packet request stuff
57 ************************************************/
58#define TX_RUP_INACTIVE 0 /* Nothing to transmit */
59#define TX_PACKET_READY 1 /* Transmit packet ready */
60#define TX_LOCK_RUP 2 /* Transmit side locked */
61
62#define RX_RUP_INACTIVE 0 /* Nothing received */
63#define RX_PACKET_READY 1 /* Packet received */
64
65#define RUP_NO_OWNER 0xff /* RUP not owned by any process */
66
67struct RUP {
68 PKT_ptr txpkt; /* Outgoing packet */
69 PKT_ptr rxpkt; /* Incoming packet */
70 WORD link; /* Which link to send down? */
71 BYTE rup_dest_unit[2]; /* Destination unit */
72 WORD handshake; /* For handshaking */
73 WORD timeout; /* Timeout */
74 WORD status; /* Status */
75 WORD txcontrol; /* Transmit control */
76 WORD rxcontrol; /* Receive control */
77 };
78
79#endif
80
81/*********** end of file ***********/
82
diff --git a/drivers/char/rio/rupstat.h b/drivers/char/rio/rupstat.h
new file mode 100644
index 000000000000..b4aafaff0d78
--- /dev/null
+++ b/drivers/char/rio/rupstat.h
@@ -0,0 +1,51 @@
1/****************************************************************************
2 ******* *******
3 ******* RUPSTAT
4 ******* *******
5 ****************************************************************************
6
7 Author : Jeremy Rolls
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36
37#ifndef _rupstat_h
38#define _rupstat_h
39
40#ifndef lint
41#ifdef SCCS_LABELS
42static char *_rio_rupstat_h_sccs = "@(#)rupstat.h 1.1" ;
43#endif
44#endif
45
46#define STATUS_SYNC 0
47#define STATUS_REQ_TOP 1
48#define STATUS_TOPOLOGY 2
49
50#endif
51
diff --git a/drivers/char/rio/sam.h b/drivers/char/rio/sam.h
new file mode 100644
index 000000000000..c1accb8cb624
--- /dev/null
+++ b/drivers/char/rio/sam.h
@@ -0,0 +1,74 @@
1/****************************************************************************
2 ******* *******
3 ******* S A M . H
4 ******* *******
5 ****************************************************************************
6
7 Author : Ian Nandhra
8 Date :
9
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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 Version : 0.01
28
29
30 Mods
31 ----------------------------------------------------------------------------
32 Date By Description
33 ----------------------------------------------------------------------------
34
35 ***************************************************************************/
36#ifndef _sam_h
37#define _sam_h 1
38
39#ifdef SCCS_LABELS
40#ifndef lint
41/* static char *_rio_sam_h_sccs = "@(#)sam.h 1.3"; */
42#endif
43#endif
44
45
46#if !defined( HOST ) && !defined( INKERNEL )
47#define RTA 1
48#endif
49
50#define NUM_FREE_LIST_UNITS 500
51
52#ifndef FALSE
53#define FALSE (short) 0x00
54#endif
55#ifndef TRUE
56#define TRUE (short) !FALSE
57#endif
58
59#define TX TRUE
60#define RX FALSE
61
62
63typedef struct FREE_LIST FREE_LIST ;
64struct FREE_LIST {
65 FREE_LIST_ptr next ;
66 FREE_LIST_ptr prev ;
67 } ;
68
69
70#endif
71/*********** end of file ***********/
72
73
74
diff --git a/drivers/char/rio/selftest.h b/drivers/char/rio/selftest.h
new file mode 100644
index 000000000000..deae48722a21
--- /dev/null
+++ b/drivers/char/rio/selftest.h
@@ -0,0 +1,73 @@
1/*
2** File: selftest.h
3**
4** Author: David Dix
5**
6** Created: 15th March 1993
7**
8** Last modified: 94/06/14
9**
10 *
11 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
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
28#ifndef _selftests_h_
29#define _selftests_h_
30
31/*
32** Selftest identifier...
33*/
34#define SELFTEST_MAGIC 0x5a5a
35
36/*
37** This is the structure of the packet that is sent back after each
38** selftest on a booting RTA.
39*/
40typedef struct {
41 short magic; /* Identifies packet type */
42 int test; /* Test number, see below */
43 unsigned int result; /* Result value */
44 unsigned int dataIn;
45 unsigned int dataOut;
46}selftestStruct;
47
48/*
49** The different tests are identified by the following data values.
50*/
51enum test {
52 TESTS_COMPLETE = 0x00,
53 MEMTEST_ADDR = 0x01,
54 MEMTEST_BIT = 0x02,
55 MEMTEST_FILL = 0x03,
56 MEMTEST_DATABUS = 0x04,
57 MEMTEST_ADDRBUS = 0x05,
58 CD1400_INIT = 0x10,
59 CD1400_LOOP = 0x11,
60 CD1400_INTERRUPT = 0x12
61};
62
63enum result {
64 E_PORT = 0x10,
65 E_TX = 0x11,
66 E_RX = 0x12,
67 E_EXCEPT = 0x13,
68 E_COMPARE = 0x14,
69 E_MODEM = 0x15,
70 E_TIMEOUT = 0x16,
71 E_INTERRUPT = 0x17
72};
73#endif /* _selftests_h_ */
diff --git a/drivers/char/rio/space.h b/drivers/char/rio/space.h
new file mode 100644
index 000000000000..72398d342051
--- /dev/null
+++ b/drivers/char/rio/space.h
@@ -0,0 +1,45 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : space.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:19
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)space.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_space_h__
34#define __rio_space_h__
35
36#ifdef SCCS_LABELS
37static char *_space_h_sccs_ = "@(#)space.h 1.2";
38#endif
39
40extern int rio_cntls;
41extern int rio_bases[];
42extern int rio_limits[];
43extern int rio_vects[];
44
45#endif /* __rio_space_h__ */
diff --git a/drivers/char/rio/sysmap.h b/drivers/char/rio/sysmap.h
new file mode 100644
index 000000000000..fdc731393576
--- /dev/null
+++ b/drivers/char/rio/sysmap.h
@@ -0,0 +1,63 @@
1
2/****************************************************************************
3 ******* *******
4 ******* S Y S T E M M A P H E A D E R
5 ******* *******
6 ****************************************************************************
7
8 Author : Ian Nandhra
9 Date :
10
11 *
12 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 Version : 0.01
29
30
31 Mods
32 ----------------------------------------------------------------------------
33 Date By Description
34 ----------------------------------------------------------------------------
35
36 ***************************************************************************/
37
38#ifndef lint
39#ifdef SCCS_LABELS
40static char *_rio_sysmap_h_sccs = "@(#)sysmap.h 1.1" ;
41#endif
42#endif
43
44#define SYSTEM_MAP_LEN 64 /* Len of System Map array */
45
46
47typedef struct SYS_MAP SYS_MAP ;
48typedef struct SYS_MAP_LINK SYS_MAP_LINK ;
49
50struct SYS_MAP_LINK {
51 short id ; /* Unit Id */
52 short link ; /* Id's Link */
53 short been_here ; /* Used by map_gen */
54 } ;
55
56struct SYS_MAP {
57 char serial_num[4] ;
58 SYS_MAP_LINK link[4] ;
59 } ;
60
61
62/*********** end of file ***********/
63
diff --git a/drivers/char/rio/timeouts.h b/drivers/char/rio/timeouts.h
new file mode 100644
index 000000000000..11b31330c901
--- /dev/null
+++ b/drivers/char/rio/timeouts.h
@@ -0,0 +1,51 @@
1
2/****************************************************************************
3 ******* *******
4 ******* T I M E O U T S
5 ******* *******
6 ****************************************************************************
7
8 Author : Ian Nandhra
9 Date :
10
11 *
12 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 Version : 0.01
29
30
31 Mods
32 ----------------------------------------------------------------------------
33 Date By Description
34 ----------------------------------------------------------------------------
35
36 ***************************************************************************/
37
38#ifndef lint
39#ifdef SCCS_LABELS
40static char *_rio_defaults_h_sccs = "@(#)timeouts.h 1.3" ;
41#endif
42#endif
43
44#define MILLISECOND (int) (1000/64) /* 15.625 low ticks */
45#define SECOND (int) 15625 /* Low priority ticks */
46
47#define TX_TIMEOUT (int) (200 * MILLISECOND)
48
49
50/*********** end of file ***********/
51
diff --git a/drivers/char/rio/top.h b/drivers/char/rio/top.h
new file mode 100644
index 000000000000..255c40d463a6
--- /dev/null
+++ b/drivers/char/rio/top.h
@@ -0,0 +1,49 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : top.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:19
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)top.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_top_h__
34#define __rio_top_h__
35
36#ifdef SCCS_LABELS
37static char *_top_h_sccs_ = "@(#)top.h 1.2";
38#endif
39
40/*
41** Topology information
42*/
43struct Top
44{
45 uchar Unit;
46 uchar Link;
47};
48
49#endif /* __rio_top_h__ */
diff --git a/drivers/char/rio/typdef.h b/drivers/char/rio/typdef.h
new file mode 100644
index 000000000000..2cb9dd693fa1
--- /dev/null
+++ b/drivers/char/rio/typdef.h
@@ -0,0 +1,82 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : typdef.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:20
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)typdef.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_typdef_h__
34#define __rio_typdef_h__
35
36#ifdef SCCS_LABELS
37static char *_typdef_h_sccs_ = "@(#)typdef.h 1.2";
38#endif
39
40#undef VPIX
41
42/*
43** IT IS REALLY, REALLY, IMPORTANT THAT BYTES ARE UNSIGNED!
44**
45** These types are ONLY to be used for refering to data structures
46** on the RIO Host card!
47*/
48typedef volatile unsigned char BYTE;
49typedef volatile unsigned short WORD;
50typedef volatile unsigned int DWORD;
51typedef volatile unsigned short RIOP;
52typedef volatile short NUMBER;
53
54
55/*
56** 27.01.199 ARG - mods to compile 'newutils' on LyxnOS -
57** These #defines are for the benefit of the 'libfuncs' library
58** only. They are not necessarily correct type mappings and
59** are here only to make the source compile.
60*/
61/* typedef unsigned int uint; */
62typedef unsigned long ulong_t;
63typedef unsigned short ushort_t;
64typedef unsigned char uchar_t;
65typedef unsigned char queue_t;
66typedef unsigned char mblk_t;
67typedef unsigned int paddr_t;
68typedef unsigned char uchar;
69
70#define TPNULL ((ushort)(0x8000))
71
72
73/*
74** RIO structures defined in other include files.
75*/
76typedef struct PKT PKT;
77typedef struct LPB LPB;
78typedef struct RUP RUP;
79typedef struct Port Port;
80typedef struct DpRam DpRam;
81
82#endif /* __rio_typdef_h__ */
diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h
new file mode 100644
index 000000000000..eddf86278abc
--- /dev/null
+++ b/drivers/char/rio/unixrup.h
@@ -0,0 +1,56 @@
1/*
2** -----------------------------------------------------------------------------
3**
4** Perle Specialix driver for Linux
5** Ported from existing RIO Driver for SCO sources.
6 *
7 * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22**
23** Module : unixrup.h
24** SID : 1.2
25** Last Modified : 11/6/98 11:34:20
26** Retrieved : 11/6/98 11:34:22
27**
28** ident @(#)unixrup.h 1.2
29**
30** -----------------------------------------------------------------------------
31*/
32
33#ifndef __rio_unixrup_h__
34#define __rio_unixrup_h__
35
36#ifdef SCCS_LABELS
37static char *_unixrup_h_sccs_ = "@(#)unixrup.h 1.2";
38#endif
39
40/*
41** UnixRup data structure. This contains pointers to actual RUPs on the
42** host card, and all the command/boot control stuff.
43*/
44struct UnixRup
45{
46 struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */
47 struct CmdBlk *CmdPendingP; /* The command currently being sent */
48 struct RUP *RupP; /* the Rup to send it to */
49 uint Id; /* Id number */
50 uint BaseSysPort; /* SysPort of first tty on this RTA */
51 uint ModTypes; /* Modules on this RTA */
52 spinlock_t RupLock; /* Lock structure for MPX */
53/* struct lockb RupLock; */ /* Lock structure for MPX */
54};
55
56#endif /* __rio_unixrup_h__ */