summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2018-11-02 18:00:26 -0400
committerDavid S. Miller <davem@davemloft.net>2018-11-06 14:03:51 -0500
commita8d6219536c16b6ab4d6e6f959032670c9368584 (patch)
treee25073053efe8e43e88b2822f7de3073756144db
parent8053e5b93eca9b011f7b79bb019bf1eeaaf96c4b (diff)
ISDN: eicon: Remove driver
I started looking at the history of this driver, and last time the maintainer was active on the mailing list was when discussing how to remove it. This was in 2012: https://lore.kernel.org/lkml/4F4DE175.30002@melware.de/ It looks to me like this has in practice been an orphan for quite a while. It's throwing warnings about stack size in a function that is in dire need of refactoring, and it's probably a case of "it's time to call it". Cc: Armin Schindler <mac@melware.de> Cc: Karsten Keil <isdn@linux-pingi.de> Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/isdn/hardware/Kconfig2
-rw-r--r--drivers/isdn/hardware/Makefile1
-rw-r--r--drivers/isdn/hardware/eicon/Kconfig51
-rw-r--r--drivers/isdn/hardware/eicon/Makefile24
-rw-r--r--drivers/isdn/hardware/eicon/adapter.h18
-rw-r--r--drivers/isdn/hardware/eicon/capi20.h699
-rw-r--r--drivers/isdn/hardware/eicon/capidtmf.c685
-rw-r--r--drivers/isdn/hardware/eicon/capidtmf.h79
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.c1219
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.h40
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c141
-rw-r--r--drivers/isdn/hardware/eicon/cardtype.h1098
-rw-r--r--drivers/isdn/hardware/eicon/cp_vers.h26
-rw-r--r--drivers/isdn/hardware/eicon/dadapter.c364
-rw-r--r--drivers/isdn/hardware/eicon/dadapter.h34
-rw-r--r--drivers/isdn/hardware/eicon/debug.c2128
-rw-r--r--drivers/isdn/hardware/eicon/debug_if.h88
-rw-r--r--drivers/isdn/hardware/eicon/debuglib.c156
-rw-r--r--drivers/isdn/hardware/eicon/debuglib.h322
-rw-r--r--drivers/isdn/hardware/eicon/dfifo.h54
-rw-r--r--drivers/isdn/hardware/eicon/di.c835
-rw-r--r--drivers/isdn/hardware/eicon/di.h118
-rw-r--r--drivers/isdn/hardware/eicon/di_dbg.h37
-rw-r--r--drivers/isdn/hardware/eicon/di_defs.h181
-rw-r--r--drivers/isdn/hardware/eicon/did_vers.h26
-rw-r--r--drivers/isdn/hardware/eicon/diddfunc.c115
-rw-r--r--drivers/isdn/hardware/eicon/diva.c666
-rw-r--r--drivers/isdn/hardware/eicon/diva.h33
-rw-r--r--drivers/isdn/hardware/eicon/diva_didd.c139
-rw-r--r--drivers/isdn/hardware/eicon/diva_dma.c94
-rw-r--r--drivers/isdn/hardware/eicon/diva_dma.h48
-rw-r--r--drivers/isdn/hardware/eicon/diva_pci.h20
-rw-r--r--drivers/isdn/hardware/eicon/divacapi.h1350
-rw-r--r--drivers/isdn/hardware/eicon/divamnt.c239
-rw-r--r--drivers/isdn/hardware/eicon/divasfunc.c237
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c562
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c848
-rw-r--r--drivers/isdn/hardware/eicon/divasproc.c412
-rw-r--r--drivers/isdn/hardware/eicon/divasync.h489
-rw-r--r--drivers/isdn/hardware/eicon/dqueue.c110
-rw-r--r--drivers/isdn/hardware/eicon/dqueue.h32
-rw-r--r--drivers/isdn/hardware/eicon/dsp_defs.h301
-rw-r--r--drivers/isdn/hardware/eicon/dsp_tst.h48
-rw-r--r--drivers/isdn/hardware/eicon/dspdids.h75
-rw-r--r--drivers/isdn/hardware/eicon/dsrv4bri.h40
-rw-r--r--drivers/isdn/hardware/eicon/dsrv_bri.h37
-rw-r--r--drivers/isdn/hardware/eicon/dsrv_pri.h38
-rw-r--r--drivers/isdn/hardware/eicon/entity.h29
-rw-r--r--drivers/isdn/hardware/eicon/helpers.h51
-rw-r--r--drivers/isdn/hardware/eicon/idifunc.c268
-rw-r--r--drivers/isdn/hardware/eicon/io.c852
-rw-r--r--drivers/isdn/hardware/eicon/io.h308
-rw-r--r--drivers/isdn/hardware/eicon/istream.c226
-rw-r--r--drivers/isdn/hardware/eicon/kst_ifc.h335
-rw-r--r--drivers/isdn/hardware/eicon/maintidi.c2194
-rw-r--r--drivers/isdn/hardware/eicon/maintidi.h171
-rw-r--r--drivers/isdn/hardware/eicon/man_defs.h133
-rw-r--r--drivers/isdn/hardware/eicon/mdm_msg.h346
-rw-r--r--drivers/isdn/hardware/eicon/message.c14954
-rw-r--r--drivers/isdn/hardware/eicon/mi_pc.h204
-rw-r--r--drivers/isdn/hardware/eicon/mntfunc.c370
-rw-r--r--drivers/isdn/hardware/eicon/os_4bri.c1132
-rw-r--r--drivers/isdn/hardware/eicon/os_4bri.h9
-rw-r--r--drivers/isdn/hardware/eicon/os_bri.c815
-rw-r--r--drivers/isdn/hardware/eicon/os_bri.h9
-rw-r--r--drivers/isdn/hardware/eicon/os_capi.h21
-rw-r--r--drivers/isdn/hardware/eicon/os_pri.c1053
-rw-r--r--drivers/isdn/hardware/eicon/os_pri.h9
-rw-r--r--drivers/isdn/hardware/eicon/pc.h738
-rw-r--r--drivers/isdn/hardware/eicon/pc_init.h267
-rw-r--r--drivers/isdn/hardware/eicon/pc_maint.h160
-rw-r--r--drivers/isdn/hardware/eicon/pkmaint.h43
-rw-r--r--drivers/isdn/hardware/eicon/platform.h369
-rw-r--r--drivers/isdn/hardware/eicon/pr_pc.h76
-rw-r--r--drivers/isdn/hardware/eicon/s_4bri.c510
-rw-r--r--drivers/isdn/hardware/eicon/s_bri.c191
-rw-r--r--drivers/isdn/hardware/eicon/s_pri.c205
-rw-r--r--drivers/isdn/hardware/eicon/sdp_hdr.h117
-rw-r--r--drivers/isdn/hardware/eicon/um_idi.c886
-rw-r--r--drivers/isdn/hardware/eicon/um_idi.h44
-rw-r--r--drivers/isdn/hardware/eicon/um_xdi.h69
-rw-r--r--drivers/isdn/hardware/eicon/xdi_adapter.h71
-rw-r--r--drivers/isdn/hardware/eicon/xdi_msg.h128
-rw-r--r--drivers/isdn/hardware/eicon/xdi_vers.h26
85 files changed, 0 insertions, 41755 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index f4855974f325..cfab497a97cc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7843,13 +7843,6 @@ F: include/linux/isdn/
7843F: include/uapi/linux/isdn.h 7843F: include/uapi/linux/isdn.h
7844F: include/uapi/linux/isdn/ 7844F: include/uapi/linux/isdn/
7845 7845
7846ISDN SUBSYSTEM (Eicon active card driver)
7847M: Armin Schindler <mac@melware.de>
7848L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
7849W: http://www.melware.de
7850S: Maintained
7851F: drivers/isdn/hardware/eicon/
7852
7853IT87 HARDWARE MONITORING DRIVER 7846IT87 HARDWARE MONITORING DRIVER
7854M: Jean Delvare <jdelvare@suse.com> 7847M: Jean Delvare <jdelvare@suse.com>
7855L: linux-hwmon@vger.kernel.org 7848L: linux-hwmon@vger.kernel.org
diff --git a/drivers/isdn/hardware/Kconfig b/drivers/isdn/hardware/Kconfig
index 30d028d24955..95c403088cce 100644
--- a/drivers/isdn/hardware/Kconfig
+++ b/drivers/isdn/hardware/Kconfig
@@ -5,5 +5,3 @@ comment "CAPI hardware drivers"
5 5
6source "drivers/isdn/hardware/avm/Kconfig" 6source "drivers/isdn/hardware/avm/Kconfig"
7 7
8source "drivers/isdn/hardware/eicon/Kconfig"
9
diff --git a/drivers/isdn/hardware/Makefile b/drivers/isdn/hardware/Makefile
index a5d8fce4c4c4..e503032b05a0 100644
--- a/drivers/isdn/hardware/Makefile
+++ b/drivers/isdn/hardware/Makefile
@@ -3,5 +3,4 @@
3# Object files in subdirectories 3# Object files in subdirectories
4 4
5obj-$(CONFIG_CAPI_AVM) += avm/ 5obj-$(CONFIG_CAPI_AVM) += avm/
6obj-$(CONFIG_CAPI_EICON) += eicon/
7obj-$(CONFIG_MISDN) += mISDN/ 6obj-$(CONFIG_MISDN) += mISDN/
diff --git a/drivers/isdn/hardware/eicon/Kconfig b/drivers/isdn/hardware/eicon/Kconfig
deleted file mode 100644
index 6082b6a5ced3..000000000000
--- a/drivers/isdn/hardware/eicon/Kconfig
+++ /dev/null
@@ -1,51 +0,0 @@
1#
2# ISDN DIVAS Eicon driver
3#
4
5menuconfig CAPI_EICON
6 bool "Active Eicon DIVA Server cards"
7 help
8 Enable support for Eicon Networks active ISDN cards.
9
10if CAPI_EICON
11
12config ISDN_DIVAS
13 tristate "Support Eicon DIVA Server cards"
14 depends on PROC_FS && PCI
15 help
16 Say Y here if you have an Eicon Networks DIVA Server PCI ISDN card.
17 In order to use this card, additional firmware is necessary, which
18 has to be downloaded into the card using the divactrl utility.
19
20if ISDN_DIVAS
21
22config ISDN_DIVAS_BRIPCI
23 bool "DIVA Server BRI/PCI support"
24 help
25 Enable support for DIVA Server BRI-PCI.
26
27config ISDN_DIVAS_PRIPCI
28 bool "DIVA Server PRI/PCI support"
29 help
30 Enable support for DIVA Server PRI-PCI.
31
32config ISDN_DIVAS_DIVACAPI
33 tristate "DIVA CAPI2.0 interface support"
34 help
35 You need this to provide the CAPI interface
36 for DIVA Server cards.
37
38config ISDN_DIVAS_USERIDI
39 tristate "DIVA User-IDI interface support"
40 help
41 Enable support for user-mode IDI interface.
42
43config ISDN_DIVAS_MAINT
44 tristate "DIVA Maint driver support"
45 depends on m
46 help
47 Enable Divas Maintenance driver.
48
49endif # ISDN_DIVAS
50
51endif # CAPI_EICON
diff --git a/drivers/isdn/hardware/eicon/Makefile b/drivers/isdn/hardware/eicon/Makefile
deleted file mode 100644
index a0ab2e2d7df0..000000000000
--- a/drivers/isdn/hardware/eicon/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2# Makefile for the Eicon DIVA ISDN drivers.
3
4# Each configuration option enables a list of files.
5
6obj-$(CONFIG_ISDN_DIVAS) += divadidd.o divas.o
7obj-$(CONFIG_ISDN_DIVAS_MAINT) += diva_mnt.o
8obj-$(CONFIG_ISDN_DIVAS_USERIDI) += diva_idi.o
9obj-$(CONFIG_ISDN_DIVAS_DIVACAPI) += divacapi.o
10
11# Multipart objects.
12
13divas-y := divasmain.o divasfunc.o di.o io.o istream.o \
14 diva.o divasproc.o diva_dma.o
15divas-$(CONFIG_ISDN_DIVAS_BRIPCI) += os_bri.o s_bri.o os_4bri.o s_4bri.o
16divas-$(CONFIG_ISDN_DIVAS_PRIPCI) += os_pri.o s_pri.o
17
18divacapi-y := capimain.o capifunc.o message.o capidtmf.o
19
20divadidd-y := diva_didd.o diddfunc.o dadapter.o
21
22diva_mnt-y := divamnt.o mntfunc.o debug.o maintidi.o
23
24diva_idi-y := divasi.o idifunc.o um_idi.o dqueue.o
diff --git a/drivers/isdn/hardware/eicon/adapter.h b/drivers/isdn/hardware/eicon/adapter.h
deleted file mode 100644
index f9b24eb8781d..000000000000
--- a/drivers/isdn/hardware/eicon/adapter.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: adapter.h,v 1.4 2004/03/21 17:26:01 armin Exp $ */
3
4#ifndef __DIVA_USER_MODE_IDI_ADAPTER_H__
5#define __DIVA_USER_MODE_IDI_ADAPTER_H__
6
7#define DIVA_UM_IDI_ADAPTER_REMOVED 0x00000001
8
9typedef struct _diva_um_idi_adapter {
10 struct list_head link;
11 DESCRIPTOR d;
12 int adapter_nr;
13 struct list_head entity_q; /* entities linked to this adapter */
14 dword status;
15} diva_um_idi_adapter_t;
16
17
18#endif
diff --git a/drivers/isdn/hardware/eicon/capi20.h b/drivers/isdn/hardware/eicon/capi20.h
deleted file mode 100644
index 391e4175b0b5..000000000000
--- a/drivers/isdn/hardware/eicon/capi20.h
+++ /dev/null
@@ -1,699 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef _INC_CAPI20
27#define _INC_CAPI20
28/* operations on message queues */
29/* the common device type for CAPI20 drivers */
30#define FILE_DEVICE_CAPI20 0x8001
31/* DEVICE_CONTROL codes for user and kernel mode applications */
32#define CAPI20_CTL_REGISTER 0x0801
33#define CAPI20_CTL_RELEASE 0x0802
34#define CAPI20_CTL_GET_MANUFACTURER 0x0805
35#define CAPI20_CTL_GET_VERSION 0x0806
36#define CAPI20_CTL_GET_SERIAL 0x0807
37#define CAPI20_CTL_GET_PROFILE 0x0808
38/* INTERNAL_DEVICE_CONTROL codes for kernel mode applicatios only */
39#define CAPI20_CTL_PUT_MESSAGE 0x0803
40#define CAPI20_CTL_GET_MESSAGE 0x0804
41/* the wrapped codes as required by the system */
42#define CAPI_CTL_CODE(f, m) CTL_CODE(FILE_DEVICE_CAPI20, f, m, FILE_ANY_ACCESS)
43#define IOCTL_CAPI_REGISTER CAPI_CTL_CODE(CAPI20_CTL_REGISTER, METHOD_BUFFERED)
44#define IOCTL_CAPI_RELEASE CAPI_CTL_CODE(CAPI20_CTL_RELEASE, METHOD_BUFFERED)
45#define IOCTL_CAPI_GET_MANUFACTURER CAPI_CTL_CODE(CAPI20_CTL_GET_MANUFACTURER, METHOD_BUFFERED)
46#define IOCTL_CAPI_GET_VERSION CAPI_CTL_CODE(CAPI20_CTL_GET_VERSION, METHOD_BUFFERED)
47#define IOCTL_CAPI_GET_SERIAL CAPI_CTL_CODE(CAPI20_CTL_GET_SERIAL, METHOD_BUFFERED)
48#define IOCTL_CAPI_GET_PROFILE CAPI_CTL_CODE(CAPI20_CTL_GET_PROFILE, METHOD_BUFFERED)
49#define IOCTL_CAPI_PUT_MESSAGE CAPI_CTL_CODE(CAPI20_CTL_PUT_MESSAGE, METHOD_BUFFERED)
50#define IOCTL_CAPI_GET_MESSAGE CAPI_CTL_CODE(CAPI20_CTL_GET_MESSAGE, METHOD_BUFFERED)
51struct divas_capi_register_params {
52 word MessageBufferSize;
53 word maxLogicalConnection;
54 word maxBDataBlocks;
55 word maxBDataLen;
56};
57struct divas_capi_version {
58 word CapiMajor;
59 word CapiMinor;
60 word ManuMajor;
61 word ManuMinor;
62};
63typedef struct api_profile_s {
64 word Number;
65 word Channels;
66 dword Global_Options;
67 dword B1_Protocols;
68 dword B2_Protocols;
69 dword B3_Protocols;
70} API_PROFILE;
71/* ISDN Common API message types */
72#define _ALERT_R 0x8001
73#define _CONNECT_R 0x8002
74#define _CONNECT_I 0x8202
75#define _CONNECT_ACTIVE_I 0x8203
76#define _DISCONNECT_R 0x8004
77#define _DISCONNECT_I 0x8204
78#define _LISTEN_R 0x8005
79#define _INFO_R 0x8008
80#define _INFO_I 0x8208
81#define _SELECT_B_REQ 0x8041
82#define _FACILITY_R 0x8080
83#define _FACILITY_I 0x8280
84#define _CONNECT_B3_R 0x8082
85#define _CONNECT_B3_I 0x8282
86#define _CONNECT_B3_ACTIVE_I 0x8283
87#define _DISCONNECT_B3_R 0x8084
88#define _DISCONNECT_B3_I 0x8284
89#define _DATA_B3_R 0x8086
90#define _DATA_B3_I 0x8286
91#define _RESET_B3_R 0x8087
92#define _RESET_B3_I 0x8287
93#define _CONNECT_B3_T90_ACTIVE_I 0x8288
94#define _MANUFACTURER_R 0x80ff
95#define _MANUFACTURER_I 0x82ff
96/* OR this to convert a REQUEST to a CONFIRM */
97#define CONFIRM 0x0100
98/* OR this to convert a INDICATION to a RESPONSE */
99#define RESPONSE 0x0100
100/*------------------------------------------------------------------*/
101/* diehl isdn private MANUFACTURER codes */
102/*------------------------------------------------------------------*/
103#define _DI_MANU_ID 0x44444944
104#define _DI_ASSIGN_PLCI 0x0001
105#define _DI_ADV_CODEC 0x0002
106#define _DI_DSP_CTRL 0x0003
107#define _DI_SIG_CTRL 0x0004
108#define _DI_RXT_CTRL 0x0005
109#define _DI_IDI_CTRL 0x0006
110#define _DI_CFG_CTRL 0x0007
111#define _DI_REMOVE_CODEC 0x0008
112#define _DI_OPTIONS_REQUEST 0x0009
113#define _DI_SSEXT_CTRL 0x000a
114#define _DI_NEGOTIATE_B3 0x000b
115/*------------------------------------------------------------------*/
116/* parameter structures */
117/*------------------------------------------------------------------*/
118/* ALERT-REQUEST */
119typedef struct {
120 byte structs[0]; /* Additional Info */
121} _ALT_REQP;
122/* ALERT-CONFIRM */
123typedef struct {
124 word Info;
125} _ALT_CONP;
126/* CONNECT-REQUEST */
127typedef struct {
128 word CIP_Value;
129 byte structs[0]; /* Called party number,
130 Called party subaddress,
131 Calling party number,
132 Calling party subaddress,
133 B_protocol,
134 BC,
135 LLC,
136 HLC,
137 Additional Info */
138} _CON_REQP;
139/* CONNECT-CONFIRM */
140typedef struct {
141 word Info;
142} _CON_CONP;
143/* CONNECT-INDICATION */
144typedef struct {
145 word CIP_Value;
146 byte structs[0]; /* Called party number,
147 Called party subaddress,
148 Calling party number,
149 Calling party subaddress,
150 BC,
151 LLC,
152 HLC,
153 Additional Info */
154} _CON_INDP;
155/* CONNECT-RESPONSE */
156typedef struct {
157 word Accept;
158 byte structs[0]; /* B_protocol,
159 Connected party number,
160 Connected party subaddress,
161 LLC */
162} _CON_RESP;
163/* CONNECT-ACTIVE-INDICATION */
164typedef struct {
165 byte structs[0]; /* Connected party number,
166 Connected party subaddress,
167 LLC */
168} _CON_A_INDP;
169/* CONNECT-ACTIVE-RESPONSE */
170typedef struct {
171 byte structs[0]; /* empty */
172} _CON_A_RESP;
173/* DISCONNECT-REQUEST */
174typedef struct {
175 byte structs[0]; /* Additional Info */
176} _DIS_REQP;
177/* DISCONNECT-CONFIRM */
178typedef struct {
179 word Info;
180} _DIS_CONP;
181/* DISCONNECT-INDICATION */
182typedef struct {
183 word Info;
184} _DIS_INDP;
185/* DISCONNECT-RESPONSE */
186typedef struct {
187 byte structs[0]; /* empty */
188} _DIS_RESP;
189/* LISTEN-REQUEST */
190typedef struct {
191 dword Info_Mask;
192 dword CIP_Mask;
193 byte structs[0]; /* Calling party number,
194 Calling party subaddress */
195} _LIS_REQP;
196/* LISTEN-CONFIRM */
197typedef struct {
198 word Info;
199} _LIS_CONP;
200/* INFO-REQUEST */
201typedef struct {
202 byte structs[0]; /* Called party number,
203 Additional Info */
204} _INF_REQP;
205/* INFO-CONFIRM */
206typedef struct {
207 word Info;
208} _INF_CONP;
209/* INFO-INDICATION */
210typedef struct {
211 word Number;
212 byte structs[0]; /* Info element */
213} _INF_INDP;
214/* INFO-RESPONSE */
215typedef struct {
216 byte structs[0]; /* empty */
217} _INF_RESP;
218/* SELECT-B-REQUEST */
219typedef struct {
220 byte structs[0]; /* B-protocol */
221} _SEL_B_REQP;
222/* SELECT-B-CONFIRM */
223typedef struct {
224 word Info;
225} _SEL_B_CONP;
226/* FACILITY-REQUEST */
227typedef struct {
228 word Selector;
229 byte structs[0]; /* Facility parameters */
230} _FAC_REQP;
231/* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */
232typedef struct {
233 byte struct_length;
234 word function;
235 byte length;
236 word SupplementaryServiceInfo;
237 dword SupportedServices;
238} _FAC_CON_STRUCTS;
239/* FACILITY-CONFIRM */
240typedef struct {
241 word Info;
242 word Selector;
243 byte structs[0]; /* Facility parameters */
244} _FAC_CONP;
245/* FACILITY-INDICATION */
246typedef struct {
247 word Selector;
248 byte structs[0]; /* Facility parameters */
249} _FAC_INDP;
250/* FACILITY-RESPONSE */
251typedef struct {
252 word Selector;
253 byte structs[0]; /* Facility parameters */
254} _FAC_RESP;
255/* CONNECT-B3-REQUEST */
256typedef struct {
257 byte structs[0]; /* NCPI */
258} _CON_B3_REQP;
259/* CONNECT-B3-CONFIRM */
260typedef struct {
261 word Info;
262} _CON_B3_CONP;
263/* CONNECT-B3-INDICATION */
264typedef struct {
265 byte structs[0]; /* NCPI */
266} _CON_B3_INDP;
267/* CONNECT-B3-RESPONSE */
268typedef struct {
269 word Accept;
270 byte structs[0]; /* NCPI */
271} _CON_B3_RESP;
272/* CONNECT-B3-ACTIVE-INDICATION */
273typedef struct {
274 byte structs[0]; /* NCPI */
275} _CON_B3_A_INDP;
276/* CONNECT-B3-ACTIVE-RESPONSE */
277typedef struct {
278 byte structs[0]; /* empty */
279} _CON_B3_A_RESP;
280/* DISCONNECT-B3-REQUEST */
281typedef struct {
282 byte structs[0]; /* NCPI */
283} _DIS_B3_REQP;
284/* DISCONNECT-B3-CONFIRM */
285typedef struct {
286 word Info;
287} _DIS_B3_CONP;
288/* DISCONNECT-B3-INDICATION */
289typedef struct {
290 word Info;
291 byte structs[0]; /* NCPI */
292} _DIS_B3_INDP;
293/* DISCONNECT-B3-RESPONSE */
294typedef struct {
295 byte structs[0]; /* empty */
296} _DIS_B3_RESP;
297/* DATA-B3-REQUEST */
298typedef struct {
299 dword Data;
300 word Data_Length;
301 word Number;
302 word Flags;
303} _DAT_B3_REQP;
304/* DATA-B3-REQUEST 64 BIT Systems */
305typedef struct {
306 dword Data;
307 word Data_Length;
308 word Number;
309 word Flags;
310 void *pData;
311} _DAT_B3_REQ64P;
312/* DATA-B3-CONFIRM */
313typedef struct {
314 word Number;
315 word Info;
316} _DAT_B3_CONP;
317/* DATA-B3-INDICATION */
318typedef struct {
319 dword Data;
320 word Data_Length;
321 word Number;
322 word Flags;
323} _DAT_B3_INDP;
324/* DATA-B3-INDICATION 64 BIT Systems */
325typedef struct {
326 dword Data;
327 word Data_Length;
328 word Number;
329 word Flags;
330 void *pData;
331} _DAT_B3_IND64P;
332/* DATA-B3-RESPONSE */
333typedef struct {
334 word Number;
335} _DAT_B3_RESP;
336/* RESET-B3-REQUEST */
337typedef struct {
338 byte structs[0]; /* NCPI */
339} _RES_B3_REQP;
340/* RESET-B3-CONFIRM */
341typedef struct {
342 word Info;
343} _RES_B3_CONP;
344/* RESET-B3-INDICATION */
345typedef struct {
346 byte structs[0]; /* NCPI */
347} _RES_B3_INDP;
348/* RESET-B3-RESPONSE */
349typedef struct {
350 byte structs[0]; /* empty */
351} _RES_B3_RESP;
352/* CONNECT-B3-T90-ACTIVE-INDICATION */
353typedef struct {
354 byte structs[0]; /* NCPI */
355} _CON_B3_T90_A_INDP;
356/* CONNECT-B3-T90-ACTIVE-RESPONSE */
357typedef struct {
358 word Reject;
359 byte structs[0]; /* NCPI */
360} _CON_B3_T90_A_RESP;
361/*------------------------------------------------------------------*/
362/* message structure */
363/*------------------------------------------------------------------*/
364typedef struct _API_MSG CAPI_MSG;
365typedef struct _MSG_HEADER CAPI_MSG_HEADER;
366struct _API_MSG {
367 struct _MSG_HEADER {
368 word length;
369 word appl_id;
370 word command;
371 word number;
372 byte controller;
373 byte plci;
374 word ncci;
375 } header;
376 union {
377 _ALT_REQP alert_req;
378 _ALT_CONP alert_con;
379 _CON_REQP connect_req;
380 _CON_CONP connect_con;
381 _CON_INDP connect_ind;
382 _CON_RESP connect_res;
383 _CON_A_INDP connect_a_ind;
384 _CON_A_RESP connect_a_res;
385 _DIS_REQP disconnect_req;
386 _DIS_CONP disconnect_con;
387 _DIS_INDP disconnect_ind;
388 _DIS_RESP disconnect_res;
389 _LIS_REQP listen_req;
390 _LIS_CONP listen_con;
391 _INF_REQP info_req;
392 _INF_CONP info_con;
393 _INF_INDP info_ind;
394 _INF_RESP info_res;
395 _SEL_B_REQP select_b_req;
396 _SEL_B_CONP select_b_con;
397 _FAC_REQP facility_req;
398 _FAC_CONP facility_con;
399 _FAC_INDP facility_ind;
400 _FAC_RESP facility_res;
401 _CON_B3_REQP connect_b3_req;
402 _CON_B3_CONP connect_b3_con;
403 _CON_B3_INDP connect_b3_ind;
404 _CON_B3_RESP connect_b3_res;
405 _CON_B3_A_INDP connect_b3_a_ind;
406 _CON_B3_A_RESP connect_b3_a_res;
407 _DIS_B3_REQP disconnect_b3_req;
408 _DIS_B3_CONP disconnect_b3_con;
409 _DIS_B3_INDP disconnect_b3_ind;
410 _DIS_B3_RESP disconnect_b3_res;
411 _DAT_B3_REQP data_b3_req;
412 _DAT_B3_REQ64P data_b3_req64;
413 _DAT_B3_CONP data_b3_con;
414 _DAT_B3_INDP data_b3_ind;
415 _DAT_B3_IND64P data_b3_ind64;
416 _DAT_B3_RESP data_b3_res;
417 _RES_B3_REQP reset_b3_req;
418 _RES_B3_CONP reset_b3_con;
419 _RES_B3_INDP reset_b3_ind;
420 _RES_B3_RESP reset_b3_res;
421 _CON_B3_T90_A_INDP connect_b3_t90_a_ind;
422 _CON_B3_T90_A_RESP connect_b3_t90_a_res;
423 byte b[200];
424 } info;
425};
426/*------------------------------------------------------------------*/
427/* non-fatal errors */
428/*------------------------------------------------------------------*/
429#define _NCPI_IGNORED 0x0001
430#define _FLAGS_IGNORED 0x0002
431#define _ALERT_IGNORED 0x0003
432/*------------------------------------------------------------------*/
433/* API function error codes */
434/*------------------------------------------------------------------*/
435#define GOOD 0x0000
436#define _TOO_MANY_APPLICATIONS 0x1001
437#define _BLOCK_TOO_SMALL 0x1002
438#define _BUFFER_TOO_BIG 0x1003
439#define _MSG_BUFFER_TOO_SMALL 0x1004
440#define _TOO_MANY_CONNECTIONS 0x1005
441#define _REG_CAPI_BUSY 0x1007
442#define _REG_RESOURCE_ERROR 0x1008
443#define _REG_CAPI_NOT_INSTALLED 0x1009
444#define _WRONG_APPL_ID 0x1101
445#define _BAD_MSG 0x1102
446#define _QUEUE_FULL 0x1103
447#define _GET_NO_MSG 0x1104
448#define _MSG_LOST 0x1105
449#define _WRONG_NOTIFY 0x1106
450#define _CAPI_BUSY 0x1107
451#define _RESOURCE_ERROR 0x1108
452#define _CAPI_NOT_INSTALLED 0x1109
453#define _NO_EXTERNAL_EQUIPMENT 0x110a
454#define _ONLY_EXTERNAL_EQUIPMENT 0x110b
455/*------------------------------------------------------------------*/
456/* addressing/coding error codes */
457/*------------------------------------------------------------------*/
458#define _WRONG_STATE 0x2001
459#define _WRONG_IDENTIFIER 0x2002
460#define _OUT_OF_PLCI 0x2003
461#define _OUT_OF_NCCI 0x2004
462#define _OUT_OF_LISTEN 0x2005
463#define _OUT_OF_FAX 0x2006
464#define _WRONG_MESSAGE_FORMAT 0x2007
465#define _OUT_OF_INTERCONNECT_RESOURCES 0x2008
466/*------------------------------------------------------------------*/
467/* configuration error codes */
468/*------------------------------------------------------------------*/
469#define _B1_NOT_SUPPORTED 0x3001
470#define _B2_NOT_SUPPORTED 0x3002
471#define _B3_NOT_SUPPORTED 0x3003
472#define _B1_PARM_NOT_SUPPORTED 0x3004
473#define _B2_PARM_NOT_SUPPORTED 0x3005
474#define _B3_PARM_NOT_SUPPORTED 0x3006
475#define _B_STACK_NOT_SUPPORTED 0x3007
476#define _NCPI_NOT_SUPPORTED 0x3008
477#define _CIP_NOT_SUPPORTED 0x3009
478#define _FLAGS_NOT_SUPPORTED 0x300a
479#define _FACILITY_NOT_SUPPORTED 0x300b
480#define _DATA_LEN_NOT_SUPPORTED 0x300c
481#define _RESET_NOT_SUPPORTED 0x300d
482#define _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED 0x300e
483#define _REQUEST_NOT_ALLOWED_IN_THIS_STATE 0x3010
484#define _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP 0x3011
485/*------------------------------------------------------------------*/
486/* reason codes */
487/*------------------------------------------------------------------*/
488#define _L1_ERROR 0x3301
489#define _L2_ERROR 0x3302
490#define _L3_ERROR 0x3303
491#define _OTHER_APPL_CONNECTED 0x3304
492#define _CAPI_GUARD_ERROR 0x3305
493#define _L3_CAUSE 0x3400
494/*------------------------------------------------------------------*/
495/* b3 reason codes */
496/*------------------------------------------------------------------*/
497#define _B_CHANNEL_LOST 0x3301
498#define _B2_ERROR 0x3302
499#define _B3_ERROR 0x3303
500/*------------------------------------------------------------------*/
501/* fax error codes */
502/*------------------------------------------------------------------*/
503#define _FAX_NO_CONNECTION 0x3311
504#define _FAX_TRAINING_ERROR 0x3312
505#define _FAX_REMOTE_REJECT 0x3313
506#define _FAX_REMOTE_ABORT 0x3314
507#define _FAX_PROTOCOL_ERROR 0x3315
508#define _FAX_TX_UNDERRUN 0x3316
509#define _FAX_RX_OVERFLOW 0x3317
510#define _FAX_LOCAL_ABORT 0x3318
511#define _FAX_PARAMETER_ERROR 0x3319
512/*------------------------------------------------------------------*/
513/* line interconnect error codes */
514/*------------------------------------------------------------------*/
515#define _LI_USER_INITIATED 0x0000
516#define _LI_LINE_NO_LONGER_AVAILABLE 0x3805
517#define _LI_INTERCONNECT_NOT_ESTABLISHED 0x3806
518#define _LI_LINES_NOT_COMPATIBLE 0x3807
519#define _LI2_USER_INITIATED 0x0000
520#define _LI2_PLCI_HAS_NO_BCHANNEL 0x3800
521#define _LI2_LINES_NOT_COMPATIBLE 0x3801
522#define _LI2_NOT_IN_SAME_INTERCONNECTION 0x3802
523/*------------------------------------------------------------------*/
524/* global options */
525/*------------------------------------------------------------------*/
526#define GL_INTERNAL_CONTROLLER_SUPPORTED 0x00000001L
527#define GL_EXTERNAL_EQUIPMENT_SUPPORTED 0x00000002L
528#define GL_HANDSET_SUPPORTED 0x00000004L
529#define GL_DTMF_SUPPORTED 0x00000008L
530#define GL_SUPPLEMENTARY_SERVICES_SUPPORTED 0x00000010L
531#define GL_CHANNEL_ALLOCATION_SUPPORTED 0x00000020L
532#define GL_BCHANNEL_OPERATION_SUPPORTED 0x00000040L
533#define GL_LINE_INTERCONNECT_SUPPORTED 0x00000080L
534#define GL_ECHO_CANCELLER_SUPPORTED 0x00000100L
535/*------------------------------------------------------------------*/
536/* protocol selection */
537/*------------------------------------------------------------------*/
538#define B1_HDLC 0
539#define B1_TRANSPARENT 1
540#define B1_V110_ASYNC 2
541#define B1_V110_SYNC 3
542#define B1_T30 4
543#define B1_HDLC_INVERTED 5
544#define B1_TRANSPARENT_R 6
545#define B1_MODEM_ALL_NEGOTIATE 7
546#define B1_MODEM_ASYNC 8
547#define B1_MODEM_SYNC_HDLC 9
548#define B2_X75 0
549#define B2_TRANSPARENT 1
550#define B2_SDLC 2
551#define B2_LAPD 3
552#define B2_T30 4
553#define B2_PPP 5
554#define B2_TRANSPARENT_NO_CRC 6
555#define B2_MODEM_EC_COMPRESSION 7
556#define B2_X75_V42BIS 8
557#define B2_V120_ASYNC 9
558#define B2_V120_ASYNC_V42BIS 10
559#define B2_V120_BIT_TRANSPARENT 11
560#define B2_LAPD_FREE_SAPI_SEL 12
561#define B3_TRANSPARENT 0
562#define B3_T90NL 1
563#define B3_ISO8208 2
564#define B3_X25_DCE 3
565#define B3_T30 4
566#define B3_T30_WITH_EXTENSIONS 5
567#define B3_RESERVED 6
568#define B3_MODEM 7
569/*------------------------------------------------------------------*/
570/* facility definitions */
571/*------------------------------------------------------------------*/
572#define SELECTOR_HANDSET 0
573#define SELECTOR_DTMF 1
574#define SELECTOR_V42BIS 2
575#define SELECTOR_SU_SERV 3
576#define SELECTOR_POWER_MANAGEMENT 4
577#define SELECTOR_LINE_INTERCONNECT 5
578#define SELECTOR_ECHO_CANCELLER 6
579/*------------------------------------------------------------------*/
580/* supplementary services definitions */
581/*------------------------------------------------------------------*/
582#define S_GET_SUPPORTED_SERVICES 0x0000
583#define S_LISTEN 0x0001
584#define S_HOLD 0x0002
585#define S_RETRIEVE 0x0003
586#define S_SUSPEND 0x0004
587#define S_RESUME 0x0005
588#define S_ECT 0x0006
589#define S_3PTY_BEGIN 0x0007
590#define S_3PTY_END 0x0008
591#define S_CALL_DEFLECTION 0x000d
592#define S_CALL_FORWARDING_START 0x0009
593#define S_CALL_FORWARDING_STOP 0x000a
594#define S_INTERROGATE_DIVERSION 0x000b /* or interrogate parameters */
595#define S_INTERROGATE_NUMBERS 0x000c
596#define S_CCBS_REQUEST 0x000f
597#define S_CCBS_DEACTIVATE 0x0010
598#define S_CCBS_INTERROGATE 0x0011
599#define S_CCBS_CALL 0x0012
600#define S_MWI_ACTIVATE 0x0013
601#define S_MWI_DEACTIVATE 0x0014
602#define S_CONF_BEGIN 0x0017
603#define S_CONF_ADD 0x0018
604#define S_CONF_SPLIT 0x0019
605#define S_CONF_DROP 0x001a
606#define S_CONF_ISOLATE 0x001b
607#define S_CONF_REATTACH 0x001c
608#define S_CCBS_ERASECALLLINKAGEID 0x800d
609#define S_CCBS_STOP_ALERTING 0x8012
610#define S_CCBS_INFO_RETAIN 0x8013
611#define S_MWI_INDICATE 0x8014
612#define S_CONF_PARTYDISC 0x8016
613#define S_CONF_NOTIFICATION 0x8017
614/* Service Masks */
615#define MASK_HOLD_RETRIEVE 0x00000001
616#define MASK_TERMINAL_PORTABILITY 0x00000002
617#define MASK_ECT 0x00000004
618#define MASK_3PTY 0x00000008
619#define MASK_CALL_FORWARDING 0x00000010
620#define MASK_CALL_DEFLECTION 0x00000020
621#define MASK_MWI 0x00000100
622#define MASK_CCNR 0x00000200
623#define MASK_CONF 0x00000400
624/*------------------------------------------------------------------*/
625/* dtmf definitions */
626/*------------------------------------------------------------------*/
627#define DTMF_LISTEN_START 1
628#define DTMF_LISTEN_STOP 2
629#define DTMF_DIGITS_SEND 3
630#define DTMF_SUCCESS 0
631#define DTMF_INCORRECT_DIGIT 1
632#define DTMF_UNKNOWN_REQUEST 2
633/*------------------------------------------------------------------*/
634/* line interconnect definitions */
635/*------------------------------------------------------------------*/
636#define LI_GET_SUPPORTED_SERVICES 0
637#define LI_REQ_CONNECT 1
638#define LI_REQ_DISCONNECT 2
639#define LI_IND_CONNECT_ACTIVE 1
640#define LI_IND_DISCONNECT 2
641#define LI_FLAG_CONFERENCE_A_B ((dword) 0x00000001L)
642#define LI_FLAG_CONFERENCE_B_A ((dword) 0x00000002L)
643#define LI_FLAG_MONITOR_A ((dword) 0x00000004L)
644#define LI_FLAG_MONITOR_B ((dword) 0x00000008L)
645#define LI_FLAG_ANNOUNCEMENT_A ((dword) 0x00000010L)
646#define LI_FLAG_ANNOUNCEMENT_B ((dword) 0x00000020L)
647#define LI_FLAG_MIX_A ((dword) 0x00000040L)
648#define LI_FLAG_MIX_B ((dword) 0x00000080L)
649#define LI_CONFERENCING_SUPPORTED ((dword) 0x00000001L)
650#define LI_MONITORING_SUPPORTED ((dword) 0x00000002L)
651#define LI_ANNOUNCEMENTS_SUPPORTED ((dword) 0x00000004L)
652#define LI_MIXING_SUPPORTED ((dword) 0x00000008L)
653#define LI_CROSS_CONTROLLER_SUPPORTED ((dword) 0x00000010L)
654#define LI2_GET_SUPPORTED_SERVICES 0
655#define LI2_REQ_CONNECT 1
656#define LI2_REQ_DISCONNECT 2
657#define LI2_IND_CONNECT_ACTIVE 1
658#define LI2_IND_DISCONNECT 2
659#define LI2_FLAG_INTERCONNECT_A_B ((dword) 0x00000001L)
660#define LI2_FLAG_INTERCONNECT_B_A ((dword) 0x00000002L)
661#define LI2_FLAG_MONITOR_B ((dword) 0x00000004L)
662#define LI2_FLAG_MIX_B ((dword) 0x00000008L)
663#define LI2_FLAG_MONITOR_X ((dword) 0x00000010L)
664#define LI2_FLAG_MIX_X ((dword) 0x00000020L)
665#define LI2_FLAG_LOOP_B ((dword) 0x00000040L)
666#define LI2_FLAG_LOOP_PC ((dword) 0x00000080L)
667#define LI2_FLAG_LOOP_X ((dword) 0x00000100L)
668#define LI2_CROSS_CONTROLLER_SUPPORTED ((dword) 0x00000001L)
669#define LI2_ASYMMETRIC_SUPPORTED ((dword) 0x00000002L)
670#define LI2_MONITORING_SUPPORTED ((dword) 0x00000004L)
671#define LI2_MIXING_SUPPORTED ((dword) 0x00000008L)
672#define LI2_REMOTE_MONITORING_SUPPORTED ((dword) 0x00000010L)
673#define LI2_REMOTE_MIXING_SUPPORTED ((dword) 0x00000020L)
674#define LI2_B_LOOPING_SUPPORTED ((dword) 0x00000040L)
675#define LI2_PC_LOOPING_SUPPORTED ((dword) 0x00000080L)
676#define LI2_X_LOOPING_SUPPORTED ((dword) 0x00000100L)
677/*------------------------------------------------------------------*/
678/* echo canceller definitions */
679/*------------------------------------------------------------------*/
680#define EC_GET_SUPPORTED_SERVICES 0
681#define EC_ENABLE_OPERATION 1
682#define EC_DISABLE_OPERATION 2
683#define EC_ENABLE_NON_LINEAR_PROCESSING 0x0001
684#define EC_DO_NOT_REQUIRE_REVERSALS 0x0002
685#define EC_DETECT_DISABLE_TONE 0x0004
686#define EC_ENABLE_ADAPTIVE_PREDELAY 0x0008
687#define EC_NON_LINEAR_PROCESSING_SUPPORTED 0x0001
688#define EC_BYPASS_ON_ANY_2100HZ_SUPPORTED 0x0002
689#define EC_BYPASS_ON_REV_2100HZ_SUPPORTED 0x0004
690#define EC_ADAPTIVE_PREDELAY_SUPPORTED 0x0008
691#define EC_BYPASS_INDICATION 1
692#define EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ 1
693#define EC_BYPASS_DUE_TO_REVERSED_2100HZ 2
694#define EC_BYPASS_RELEASED 3
695/*------------------------------------------------------------------*/
696/* function prototypes */
697/*------------------------------------------------------------------*/
698/*------------------------------------------------------------------*/
699#endif /* _INC_CAPI20 */
diff --git a/drivers/isdn/hardware/eicon/capidtmf.c b/drivers/isdn/hardware/eicon/capidtmf.c
deleted file mode 100644
index e3f778415199..000000000000
--- a/drivers/isdn/hardware/eicon/capidtmf.c
+++ /dev/null
@@ -1,685 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26
27#include "platform.h"
28
29
30
31
32
33
34
35
36
37#include "capidtmf.h"
38
39/* #define TRACE_ */
40
41#define FILE_ "CAPIDTMF.C"
42
43/*---------------------------------------------------------------------------*/
44
45
46#define trace(a)
47
48
49
50/*---------------------------------------------------------------------------*/
51
52static short capidtmf_expand_table_alaw[0x0100] =
53{
54 -5504, 5504, -344, 344, -22016, 22016, -1376, 1376,
55 -2752, 2752, -88, 88, -11008, 11008, -688, 688,
56 -7552, 7552, -472, 472, -30208, 30208, -1888, 1888,
57 -3776, 3776, -216, 216, -15104, 15104, -944, 944,
58 -4480, 4480, -280, 280, -17920, 17920, -1120, 1120,
59 -2240, 2240, -24, 24, -8960, 8960, -560, 560,
60 -6528, 6528, -408, 408, -26112, 26112, -1632, 1632,
61 -3264, 3264, -152, 152, -13056, 13056, -816, 816,
62 -6016, 6016, -376, 376, -24064, 24064, -1504, 1504,
63 -3008, 3008, -120, 120, -12032, 12032, -752, 752,
64 -8064, 8064, -504, 504, -32256, 32256, -2016, 2016,
65 -4032, 4032, -248, 248, -16128, 16128, -1008, 1008,
66 -4992, 4992, -312, 312, -19968, 19968, -1248, 1248,
67 -2496, 2496, -56, 56, -9984, 9984, -624, 624,
68 -7040, 7040, -440, 440, -28160, 28160, -1760, 1760,
69 -3520, 3520, -184, 184, -14080, 14080, -880, 880,
70 -5248, 5248, -328, 328, -20992, 20992, -1312, 1312,
71 -2624, 2624, -72, 72, -10496, 10496, -656, 656,
72 -7296, 7296, -456, 456, -29184, 29184, -1824, 1824,
73 -3648, 3648, -200, 200, -14592, 14592, -912, 912,
74 -4224, 4224, -264, 264, -16896, 16896, -1056, 1056,
75 -2112, 2112, -8, 8, -8448, 8448, -528, 528,
76 -6272, 6272, -392, 392, -25088, 25088, -1568, 1568,
77 -3136, 3136, -136, 136, -12544, 12544, -784, 784,
78 -5760, 5760, -360, 360, -23040, 23040, -1440, 1440,
79 -2880, 2880, -104, 104, -11520, 11520, -720, 720,
80 -7808, 7808, -488, 488, -31232, 31232, -1952, 1952,
81 -3904, 3904, -232, 232, -15616, 15616, -976, 976,
82 -4736, 4736, -296, 296, -18944, 18944, -1184, 1184,
83 -2368, 2368, -40, 40, -9472, 9472, -592, 592,
84 -6784, 6784, -424, 424, -27136, 27136, -1696, 1696,
85 -3392, 3392, -168, 168, -13568, 13568, -848, 848
86};
87
88static short capidtmf_expand_table_ulaw[0x0100] =
89{
90 -32124, 32124, -1884, 1884, -7932, 7932, -372, 372,
91 -15996, 15996, -876, 876, -3900, 3900, -120, 120,
92 -23932, 23932, -1372, 1372, -5884, 5884, -244, 244,
93 -11900, 11900, -620, 620, -2876, 2876, -56, 56,
94 -28028, 28028, -1628, 1628, -6908, 6908, -308, 308,
95 -13948, 13948, -748, 748, -3388, 3388, -88, 88,
96 -19836, 19836, -1116, 1116, -4860, 4860, -180, 180,
97 -9852, 9852, -492, 492, -2364, 2364, -24, 24,
98 -30076, 30076, -1756, 1756, -7420, 7420, -340, 340,
99 -14972, 14972, -812, 812, -3644, 3644, -104, 104,
100 -21884, 21884, -1244, 1244, -5372, 5372, -212, 212,
101 -10876, 10876, -556, 556, -2620, 2620, -40, 40,
102 -25980, 25980, -1500, 1500, -6396, 6396, -276, 276,
103 -12924, 12924, -684, 684, -3132, 3132, -72, 72,
104 -17788, 17788, -988, 988, -4348, 4348, -148, 148,
105 -8828, 8828, -428, 428, -2108, 2108, -8, 8,
106 -31100, 31100, -1820, 1820, -7676, 7676, -356, 356,
107 -15484, 15484, -844, 844, -3772, 3772, -112, 112,
108 -22908, 22908, -1308, 1308, -5628, 5628, -228, 228,
109 -11388, 11388, -588, 588, -2748, 2748, -48, 48,
110 -27004, 27004, -1564, 1564, -6652, 6652, -292, 292,
111 -13436, 13436, -716, 716, -3260, 3260, -80, 80,
112 -18812, 18812, -1052, 1052, -4604, 4604, -164, 164,
113 -9340, 9340, -460, 460, -2236, 2236, -16, 16,
114 -29052, 29052, -1692, 1692, -7164, 7164, -324, 324,
115 -14460, 14460, -780, 780, -3516, 3516, -96, 96,
116 -20860, 20860, -1180, 1180, -5116, 5116, -196, 196,
117 -10364, 10364, -524, 524, -2492, 2492, -32, 32,
118 -24956, 24956, -1436, 1436, -6140, 6140, -260, 260,
119 -12412, 12412, -652, 652, -3004, 3004, -64, 64,
120 -16764, 16764, -924, 924, -4092, 4092, -132, 132,
121 -8316, 8316, -396, 396, -1980, 1980, 0, 0
122};
123
124
125/*---------------------------------------------------------------------------*/
126
127static short capidtmf_recv_window_function[CAPIDTMF_RECV_ACCUMULATE_CYCLES] =
128{
129 -500L, -999L, -1499L, -1998L, -2496L, -2994L, -3491L, -3988L,
130 -4483L, -4978L, -5471L, -5963L, -6454L, -6943L, -7431L, -7917L,
131 -8401L, -8883L, -9363L, -9840L, -10316L, -10789L, -11259L, -11727L,
132 -12193L, -12655L, -13115L, -13571L, -14024L, -14474L, -14921L, -15364L,
133 -15804L, -16240L, -16672L, -17100L, -17524L, -17944L, -18360L, -18772L,
134 -19180L, -19583L, -19981L, -20375L, -20764L, -21148L, -21527L, -21901L,
135 -22270L, -22634L, -22993L, -23346L, -23694L, -24037L, -24374L, -24705L,
136 -25030L, -25350L, -25664L, -25971L, -26273L, -26568L, -26858L, -27141L,
137 -27418L, -27688L, -27952L, -28210L, -28461L, -28705L, -28943L, -29174L,
138 -29398L, -29615L, -29826L, -30029L, -30226L, -30415L, -30598L, -30773L,
139 -30941L, -31102L, -31256L, -31402L, -31541L, -31673L, -31797L, -31914L,
140 -32024L, -32126L, -32221L, -32308L, -32388L, -32460L, -32524L, -32581L,
141 -32631L, -32673L, -32707L, -32734L, -32753L, -32764L, -32768L, -32764L,
142 -32753L, -32734L, -32707L, -32673L, -32631L, -32581L, -32524L, -32460L,
143 -32388L, -32308L, -32221L, -32126L, -32024L, -31914L, -31797L, -31673L,
144 -31541L, -31402L, -31256L, -31102L, -30941L, -30773L, -30598L, -30415L,
145 -30226L, -30029L, -29826L, -29615L, -29398L, -29174L, -28943L, -28705L,
146 -28461L, -28210L, -27952L, -27688L, -27418L, -27141L, -26858L, -26568L,
147 -26273L, -25971L, -25664L, -25350L, -25030L, -24705L, -24374L, -24037L,
148 -23694L, -23346L, -22993L, -22634L, -22270L, -21901L, -21527L, -21148L,
149 -20764L, -20375L, -19981L, -19583L, -19180L, -18772L, -18360L, -17944L,
150 -17524L, -17100L, -16672L, -16240L, -15804L, -15364L, -14921L, -14474L,
151 -14024L, -13571L, -13115L, -12655L, -12193L, -11727L, -11259L, -10789L,
152 -10316L, -9840L, -9363L, -8883L, -8401L, -7917L, -7431L, -6943L,
153 -6454L, -5963L, -5471L, -4978L, -4483L, -3988L, -3491L, -2994L,
154 -2496L, -1998L, -1499L, -999L, -500L,
155};
156
157static byte capidtmf_leading_zeroes_table[0x100] =
158{
159 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
160 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
161 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
162 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
163 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
164 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
165 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
166 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
175};
176
177#define capidtmf_byte_leading_zeroes(b) (capidtmf_leading_zeroes_table[(BYTE)(b)])
178#define capidtmf_word_leading_zeroes(w) (((w) & 0xff00) ? capidtmf_leading_zeroes_table[(w) >> 8] : 8 + capidtmf_leading_zeroes_table[(w)])
179#define capidtmf_dword_leading_zeroes(d) (((d) & 0xffff0000L) ? (((d) & 0xff000000L) ? capidtmf_leading_zeroes_table[(d) >> 24] : 8 + capidtmf_leading_zeroes_table[(d) >> 16]) : (((d) & 0xff00) ? 16 + capidtmf_leading_zeroes_table[(d) >> 8] : 24 + capidtmf_leading_zeroes_table[(d)]))
180
181
182/*---------------------------------------------------------------------------*/
183
184
185static void capidtmf_goertzel_loop(long *buffer, long *coeffs, short *sample, long count)
186{
187 int i, j;
188 long c, d, q0, q1, q2;
189
190 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1; i++)
191 {
192 q1 = buffer[i];
193 q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
194 d = coeffs[i] >> 1;
195 c = d << 1;
196 if (c >= 0)
197 {
198 for (j = 0; j < count; j++)
199 {
200 q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15);
201 q2 = q1;
202 q1 = q0;
203 }
204 }
205 else
206 {
207 c = -c;
208 d = -d;
209 for (j = 0; j < count; j++)
210 {
211 q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15));
212 q2 = q1;
213 q1 = q0;
214 }
215 }
216 buffer[i] = q1;
217 buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
218 }
219 q1 = buffer[i];
220 q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
221 c = (coeffs[i] >> 1) << 1;
222 if (c >= 0)
223 {
224 for (j = 0; j < count; j++)
225 {
226 q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15);
227 q2 = q1;
228 q1 = q0;
229 c -= CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
230 }
231 }
232 else
233 {
234 c = -c;
235 for (j = 0; j < count; j++)
236 {
237 q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15));
238 q2 = q1;
239 q1 = q0;
240 c += CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
241 }
242 }
243 coeffs[i] = c;
244 buffer[i] = q1;
245 buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
246}
247
248
249static void capidtmf_goertzel_result(long *buffer, long *coeffs)
250{
251 int i;
252 long d, e, q1, q2, lo, mid, hi;
253 dword k;
254
255 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
256 {
257 q1 = buffer[i];
258 q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
259 d = coeffs[i] >> 1;
260 if (d >= 0)
261 d = ((d << 1) * (-q1 >> 16)) + (((dword)(((dword) d) * ((dword)(-q1 & 0xffff)))) >> 15);
262 else
263 d = ((-d << 1) * (-q1 >> 16)) + (((dword)(((dword) -d) * ((dword)(-q1 & 0xffff)))) >> 15);
264 e = (q2 >= 0) ? q2 : -q2;
265 if (d >= 0)
266 {
267 k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
268 lo = k & 0xffff;
269 mid = k >> 16;
270 k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
271 mid += k & 0xffff;
272 hi = k >> 16;
273 k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
274 mid += k & 0xffff;
275 hi += k >> 16;
276 hi += ((dword)(d >> 16)) * ((dword)(e >> 16));
277 }
278 else
279 {
280 d = -d;
281 k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
282 lo = -((long)(k & 0xffff));
283 mid = -((long)(k >> 16));
284 k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
285 mid -= k & 0xffff;
286 hi = -((long)(k >> 16));
287 k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
288 mid -= k & 0xffff;
289 hi -= k >> 16;
290 hi -= ((dword)(d >> 16)) * ((dword)(e >> 16));
291 }
292 if (q2 < 0)
293 {
294 lo = -lo;
295 mid = -mid;
296 hi = -hi;
297 }
298 d = (q1 >= 0) ? q1 : -q1;
299 k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
300 lo += k & 0xffff;
301 mid += k >> 16;
302 k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
303 mid += (k & 0xffff) << 1;
304 hi += (k >> 16) << 1;
305 hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
306 d = (q2 >= 0) ? q2 : -q2;
307 k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
308 lo += k & 0xffff;
309 mid += k >> 16;
310 k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
311 mid += (k & 0xffff) << 1;
312 hi += (k >> 16) << 1;
313 hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
314 mid += lo >> 16;
315 hi += mid >> 16;
316 buffer[i] = (lo & 0xffff) | (mid << 16);
317 buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = hi;
318 }
319}
320
321
322/*---------------------------------------------------------------------------*/
323
324#define CAPIDTMF_RECV_GUARD_SNR_INDEX_697 0
325#define CAPIDTMF_RECV_GUARD_SNR_INDEX_770 1
326#define CAPIDTMF_RECV_GUARD_SNR_INDEX_852 2
327#define CAPIDTMF_RECV_GUARD_SNR_INDEX_941 3
328#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1209 4
329#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1336 5
330#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1477 6
331#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1633 7
332#define CAPIDTMF_RECV_GUARD_SNR_INDEX_635 8
333#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1010 9
334#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1140 10
335#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1272 11
336#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1405 12
337#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1555 13
338#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1715 14
339#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1875 15
340
341#define CAPIDTMF_RECV_GUARD_SNR_DONTCARE 0xc000
342#define CAPIDTMF_RECV_NO_DIGIT 0xff
343#define CAPIDTMF_RECV_TIME_GRANULARITY (CAPIDTMF_RECV_ACCUMULATE_CYCLES + 1)
344
345#define CAPIDTMF_RECV_INDICATION_DIGIT 0x0001
346
347static long capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
348{
349 0xda97L * 2, /* 697 Hz (Low group 697 Hz) */
350 0xd299L * 2, /* 770 Hz (Low group 770 Hz) */
351 0xc8cbL * 2, /* 852 Hz (Low group 852 Hz) */
352 0xbd36L * 2, /* 941 Hz (Low group 941 Hz) */
353 0x9501L * 2, /* 1209 Hz (High group 1209 Hz) */
354 0x7f89L * 2, /* 1336 Hz (High group 1336 Hz) */
355 0x6639L * 2, /* 1477 Hz (High group 1477 Hz) */
356 0x48c6L * 2, /* 1633 Hz (High group 1633 Hz) */
357 0xe14cL * 2, /* 630 Hz (Lower guard of low group 631 Hz) */
358 0xb2e0L * 2, /* 1015 Hz (Upper guard of low group 1039 Hz) */
359 0xa1a0L * 2, /* 1130 Hz (Lower guard of high group 1140 Hz) */
360 0x8a87L * 2, /* 1272 Hz (Guard between 1209 Hz and 1336 Hz: 1271 Hz) */
361 0x7353L * 2, /* 1405 Hz (2nd harmonics of 697 Hz and guard between 1336 Hz and 1477 Hz: 1405 Hz) */
362 0x583bL * 2, /* 1552 Hz (2nd harmonics of 770 Hz and guard between 1477 Hz and 1633 Hz: 1553 Hz) */
363 0x37d8L * 2, /* 1720 Hz (2nd harmonics of 852 Hz and upper guard of high group: 1715 Hz) */
364 0x0000L * 2 /* 100-630 Hz (fundamentals) */
365};
366
367
368static word capidtmf_recv_guard_snr_low_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
369{
370 14, /* Low group peak versus 697 Hz */
371 14, /* Low group peak versus 770 Hz */
372 16, /* Low group peak versus 852 Hz */
373 16, /* Low group peak versus 941 Hz */
374 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1209 Hz */
375 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1336 Hz */
376 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1477 Hz */
377 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1633 Hz */
378 14, /* Low group peak versus 635 Hz */
379 16, /* Low group peak versus 1010 Hz */
380 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1140 Hz */
381 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1272 Hz */
382 DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 8, /* Low group peak versus 1405 Hz */
383 DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1555 Hz */
384 DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1715 Hz */
385 12 /* Low group peak versus 100-630 Hz */
386};
387
388
389static word capidtmf_recv_guard_snr_high_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
390{
391 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 697 Hz */
392 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 770 Hz */
393 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 852 Hz */
394 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 941 Hz */
395 20, /* High group peak versus 1209 Hz */
396 20, /* High group peak versus 1336 Hz */
397 20, /* High group peak versus 1477 Hz */
398 20, /* High group peak versus 1633 Hz */
399 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 635 Hz */
400 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 1010 Hz */
401 16, /* High group peak versus 1140 Hz */
402 4, /* High group peak versus 1272 Hz */
403 6, /* High group peak versus 1405 Hz */
404 8, /* High group peak versus 1555 Hz */
405 16, /* High group peak versus 1715 Hz */
406 12 /* High group peak versus 100-630 Hz */
407};
408
409
410/*---------------------------------------------------------------------------*/
411
412static void capidtmf_recv_init(t_capidtmf_state *p_state)
413{
414 p_state->recv.min_gap_duration = 1;
415 p_state->recv.min_digit_duration = 1;
416
417 p_state->recv.cycle_counter = 0;
418 p_state->recv.current_digit_on_time = 0;
419 p_state->recv.current_digit_off_time = 0;
420 p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
421
422 p_state->recv.digit_write_pos = 0;
423 p_state->recv.digit_read_pos = 0;
424 p_state->recv.indication_state = 0;
425 p_state->recv.indication_state_ack = 0;
426 p_state->recv.state = CAPIDTMF_RECV_STATE_IDLE;
427}
428
429
430void capidtmf_recv_enable(t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration)
431{
432 p_state->recv.indication_state_ack &= CAPIDTMF_RECV_INDICATION_DIGIT;
433 p_state->recv.min_digit_duration = (word)(((((dword) min_digit_duration) * 8) +
434 ((dword)(CAPIDTMF_RECV_TIME_GRANULARITY / 2))) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
435 if (p_state->recv.min_digit_duration <= 1)
436 p_state->recv.min_digit_duration = 1;
437 else
438 (p_state->recv.min_digit_duration)--;
439 p_state->recv.min_gap_duration =
440 (word)((((dword) min_gap_duration) * 8) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
441 if (p_state->recv.min_gap_duration <= 1)
442 p_state->recv.min_gap_duration = 1;
443 else
444 (p_state->recv.min_gap_duration)--;
445 p_state->recv.state |= CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
446}
447
448
449void capidtmf_recv_disable(t_capidtmf_state *p_state)
450{
451 p_state->recv.state &= ~CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
452 if (p_state->recv.state == CAPIDTMF_RECV_STATE_IDLE)
453 capidtmf_recv_init(p_state);
454 else
455 {
456 p_state->recv.cycle_counter = 0;
457 p_state->recv.current_digit_on_time = 0;
458 p_state->recv.current_digit_off_time = 0;
459 p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
460 }
461}
462
463
464word capidtmf_recv_indication(t_capidtmf_state *p_state, byte *buffer)
465{
466 word i, j, k, flags;
467
468 flags = p_state->recv.indication_state ^ p_state->recv.indication_state_ack;
469 p_state->recv.indication_state_ack ^= flags & CAPIDTMF_RECV_INDICATION_DIGIT;
470 if (p_state->recv.digit_write_pos != p_state->recv.digit_read_pos)
471 {
472 i = 0;
473 k = p_state->recv.digit_write_pos;
474 j = p_state->recv.digit_read_pos;
475 do
476 {
477 buffer[i++] = p_state->recv.digit_buffer[j];
478 j = (j == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 0 : j + 1;
479 } while (j != k);
480 p_state->recv.digit_read_pos = k;
481 return (i);
482 }
483 p_state->recv.indication_state_ack ^= flags;
484 return (0);
485}
486
487
488#define CAPIDTMF_RECV_WINDOWED_SAMPLES 32
489
490void capidtmf_recv_block(t_capidtmf_state *p_state, byte *buffer, word length)
491{
492 byte result_digit;
493 word sample_number, cycle_counter, n, i;
494 word low_peak, high_peak;
495 dword lo, hi;
496 byte *p;
497 short *q;
498 byte goertzel_result_buffer[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
499 short windowed_sample_buffer[CAPIDTMF_RECV_WINDOWED_SAMPLES];
500
501
502 if (p_state->recv.state & CAPIDTMF_RECV_STATE_DTMF_ACTIVE)
503 {
504 cycle_counter = p_state->recv.cycle_counter;
505 sample_number = 0;
506 while (sample_number < length)
507 {
508 if (cycle_counter < CAPIDTMF_RECV_ACCUMULATE_CYCLES)
509 {
510 if (cycle_counter == 0)
511 {
512 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
513 {
514 p_state->recv.goertzel_buffer[0][i] = 0;
515 p_state->recv.goertzel_buffer[1][i] = 0;
516 }
517 }
518 n = CAPIDTMF_RECV_ACCUMULATE_CYCLES - cycle_counter;
519 if (n > length - sample_number)
520 n = length - sample_number;
521 if (n > CAPIDTMF_RECV_WINDOWED_SAMPLES)
522 n = CAPIDTMF_RECV_WINDOWED_SAMPLES;
523 p = buffer + sample_number;
524 q = capidtmf_recv_window_function + cycle_counter;
525 if (p_state->ulaw)
526 {
527 for (i = 0; i < n; i++)
528 {
529 windowed_sample_buffer[i] =
530 (short)((capidtmf_expand_table_ulaw[p[i]] * ((long)(q[i]))) >> 15);
531 }
532 }
533 else
534 {
535 for (i = 0; i < n; i++)
536 {
537 windowed_sample_buffer[i] =
538 (short)((capidtmf_expand_table_alaw[p[i]] * ((long)(q[i]))) >> 15);
539 }
540 }
541 capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1] = CAPIDTMF_RECV_FUNDAMENTAL_OFFSET;
542 capidtmf_goertzel_loop(p_state->recv.goertzel_buffer[0],
543 capidtmf_recv_goertzel_coef_table, windowed_sample_buffer, n);
544 cycle_counter += n;
545 sample_number += n;
546 }
547 else
548 {
549 capidtmf_goertzel_result(p_state->recv.goertzel_buffer[0],
550 capidtmf_recv_goertzel_coef_table);
551 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
552 {
553 lo = (dword)(p_state->recv.goertzel_buffer[0][i]);
554 hi = (dword)(p_state->recv.goertzel_buffer[1][i]);
555 if (hi != 0)
556 {
557 n = capidtmf_dword_leading_zeroes(hi);
558 hi = (hi << n) | (lo >> (32 - n));
559 }
560 else
561 {
562 n = capidtmf_dword_leading_zeroes(lo);
563 hi = lo << n;
564 n += 32;
565 }
566 n = 195 - 3 * n;
567 if (hi >= 0xcb300000L)
568 n += 2;
569 else if (hi >= 0xa1450000L)
570 n++;
571 goertzel_result_buffer[i] = (byte) n;
572 }
573 low_peak = DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT;
574 result_digit = CAPIDTMF_RECV_NO_DIGIT;
575 for (i = 0; i < CAPIDTMF_LOW_GROUP_FREQUENCIES; i++)
576 {
577 if (goertzel_result_buffer[i] > low_peak)
578 {
579 low_peak = goertzel_result_buffer[i];
580 result_digit = (byte) i;
581 }
582 }
583 high_peak = DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT;
584 n = CAPIDTMF_RECV_NO_DIGIT;
585 for (i = CAPIDTMF_LOW_GROUP_FREQUENCIES; i < CAPIDTMF_RECV_BASE_FREQUENCY_COUNT; i++)
586 {
587 if (goertzel_result_buffer[i] > high_peak)
588 {
589 high_peak = goertzel_result_buffer[i];
590 n = (i - CAPIDTMF_LOW_GROUP_FREQUENCIES) << 2;
591 }
592 }
593 result_digit |= (byte) n;
594 if (low_peak + DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT < high_peak)
595 result_digit = CAPIDTMF_RECV_NO_DIGIT;
596 if (high_peak + DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT < low_peak)
597 result_digit = CAPIDTMF_RECV_NO_DIGIT;
598 n = 0;
599 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
600 {
601 if ((((short)(low_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_low_table[i])) < 0)
602 || (((short)(high_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_high_table[i])) < 0))
603 {
604 n++;
605 }
606 }
607 if (n != 2)
608 result_digit = CAPIDTMF_RECV_NO_DIGIT;
609
610 if (result_digit == CAPIDTMF_RECV_NO_DIGIT)
611 {
612 if (p_state->recv.current_digit_on_time != 0)
613 {
614 if (++(p_state->recv.current_digit_off_time) >= p_state->recv.min_gap_duration)
615 {
616 p_state->recv.current_digit_on_time = 0;
617 p_state->recv.current_digit_off_time = 0;
618 }
619 }
620 else
621 {
622 if (p_state->recv.current_digit_off_time != 0)
623 (p_state->recv.current_digit_off_time)--;
624 }
625 }
626 else
627 {
628 if ((p_state->recv.current_digit_on_time == 0)
629 && (p_state->recv.current_digit_off_time != 0))
630 {
631 (p_state->recv.current_digit_off_time)--;
632 }
633 else
634 {
635 n = p_state->recv.current_digit_off_time;
636 if ((p_state->recv.current_digit_on_time != 0)
637 && (result_digit != p_state->recv.current_digit_value))
638 {
639 p_state->recv.current_digit_on_time = 0;
640 n = 0;
641 }
642 p_state->recv.current_digit_value = result_digit;
643 p_state->recv.current_digit_off_time = 0;
644 if (p_state->recv.current_digit_on_time != 0xffff)
645 {
646 p_state->recv.current_digit_on_time += n + 1;
647 if (p_state->recv.current_digit_on_time >= p_state->recv.min_digit_duration)
648 {
649 p_state->recv.current_digit_on_time = 0xffff;
650 i = (p_state->recv.digit_write_pos == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ?
651 0 : p_state->recv.digit_write_pos + 1;
652 if (i == p_state->recv.digit_read_pos)
653 {
654 trace(dprintf("%s,%d: Receive digit overrun",
655 (char *)(FILE_), __LINE__));
656 }
657 else
658 {
659 p_state->recv.digit_buffer[p_state->recv.digit_write_pos] = result_digit;
660 p_state->recv.digit_write_pos = i;
661 p_state->recv.indication_state =
662 (p_state->recv.indication_state & ~CAPIDTMF_RECV_INDICATION_DIGIT) |
663 (~p_state->recv.indication_state_ack & CAPIDTMF_RECV_INDICATION_DIGIT);
664 }
665 }
666 }
667 }
668 }
669 cycle_counter = 0;
670 sample_number++;
671 }
672 }
673 p_state->recv.cycle_counter = cycle_counter;
674 }
675}
676
677
678void capidtmf_init(t_capidtmf_state *p_state, byte ulaw)
679{
680 p_state->ulaw = ulaw;
681 capidtmf_recv_init(p_state);
682}
683
684
685/*---------------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/capidtmf.h b/drivers/isdn/hardware/eicon/capidtmf.h
deleted file mode 100644
index 0a9cf59bb224..000000000000
--- a/drivers/isdn/hardware/eicon/capidtmf.h
+++ /dev/null
@@ -1,79 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef CAPIDTMF_H_
27#define CAPIDTMF_H_
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30#define CAPIDTMF_TONE_GROUP_COUNT 2
31#define CAPIDTMF_LOW_GROUP_FREQUENCIES 4
32#define CAPIDTMF_HIGH_GROUP_FREQUENCIES 4
33#define DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT 50 /* -52 dBm */
34#define DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT 50 /* -52 dBm */
35#define DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT 10 /* dB */
36#define DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT 10 /* dB */
37#define DSPDTMF_RX_HARMONICS_SEL_DEFAULT 12 /* dB */
38#define CAPIDTMF_RECV_BASE_FREQUENCY_COUNT (CAPIDTMF_LOW_GROUP_FREQUENCIES + CAPIDTMF_HIGH_GROUP_FREQUENCIES)
39#define CAPIDTMF_RECV_GUARD_FREQUENCY_COUNT 8
40#define CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT (CAPIDTMF_RECV_BASE_FREQUENCY_COUNT + CAPIDTMF_RECV_GUARD_FREQUENCY_COUNT)
41#define CAPIDTMF_RECV_POSITIVE_COEFF_COUNT 16
42#define CAPIDTMF_RECV_NEGATIVE_COEFF_COUNT (CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - CAPIDTMF_RECV_POSITIVE_COEFF_COUNT)
43#define CAPIDTMF_RECV_ACCUMULATE_CYCLES 205
44#define CAPIDTMF_RECV_FUNDAMENTAL_OFFSET (0xff35L * 2)
45#define CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT (0x0028L * 2)
46#define CAPIDTMF_RECV_DIGIT_BUFFER_SIZE 32
47#define CAPIDTMF_RECV_STATE_IDLE 0x00
48#define CAPIDTMF_RECV_STATE_DTMF_ACTIVE 0x01
49typedef struct tag_capidtmf_recv_state
50{
51 byte digit_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE];
52 word digit_write_pos;
53 word digit_read_pos;
54 word indication_state;
55 word indication_state_ack;
56 long goertzel_buffer[2][CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
57 word min_gap_duration;
58 word min_digit_duration;
59 word cycle_counter;
60 word current_digit_on_time;
61 word current_digit_off_time;
62 byte current_digit_value;
63 byte state;
64} t_capidtmf_recv_state;
65typedef struct tag_capidtmf_state
66{
67 byte ulaw;
68 t_capidtmf_recv_state recv;
69} t_capidtmf_state;
70word capidtmf_recv_indication(t_capidtmf_state *p_state, byte *buffer);
71void capidtmf_recv_block(t_capidtmf_state *p_state, byte *buffer, word length);
72void capidtmf_init(t_capidtmf_state *p_state, byte ulaw);
73void capidtmf_recv_enable(t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration);
74void capidtmf_recv_disable(t_capidtmf_state *p_state);
75#define capidtmf_indication(p_state, buffer) (((p_state)->recv.indication_state != (p_state)->recv.indication_state_ack) ? capidtmf_recv_indication(p_state, buffer) : 0)
76#define capidtmf_recv_process_block(p_state, buffer, length) { if ((p_state)->recv.state != CAPIDTMF_RECV_STATE_IDLE) capidtmf_recv_block(p_state, buffer, length); }
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79#endif
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
deleted file mode 100644
index 7a0bdbdd87ea..000000000000
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ /dev/null
@@ -1,1219 +0,0 @@
1/* $Id: capifunc.c,v 1.61.4.7 2005/02/11 19:40:25 armin Exp $
2 *
3 * ISDN interface module for Eicon active cards DIVA.
4 * CAPI Interface common functions
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 *
12 */
13
14#include "platform.h"
15#include "os_capi.h"
16#include "di_defs.h"
17#include "capi20.h"
18#include "divacapi.h"
19#include "divasync.h"
20#include "capifunc.h"
21
22#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
23#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
24
25DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;
26APPL *application = (APPL *) NULL;
27byte max_appl = MAX_APPL;
28byte max_adapter = 0;
29static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL;
30
31byte UnMapController(byte);
32char DRIVERRELEASE_CAPI[32];
33
34extern void AutomaticLaw(DIVA_CAPI_ADAPTER *);
35extern void callback(ENTITY *);
36extern word api_remove_start(void);
37extern word CapiRelease(word);
38extern word CapiRegister(word);
39extern word api_put(APPL *, CAPI_MSG *);
40
41static diva_os_spin_lock_t api_lock;
42
43static LIST_HEAD(cards);
44
45static dword notify_handle;
46static void DIRequest(ENTITY *e);
47static DESCRIPTOR MAdapter;
48static DESCRIPTOR DAdapter;
49static byte ControllerMap[MAX_DESCRIPTORS + 1];
50
51
52static void diva_register_appl(struct capi_ctr *, __u16,
53 capi_register_params *);
54static void diva_release_appl(struct capi_ctr *, __u16);
55static char *diva_procinfo(struct capi_ctr *);
56static u16 diva_send_message(struct capi_ctr *,
57 diva_os_message_buffer_s *);
58extern void diva_os_set_controller_struct(struct capi_ctr *);
59
60extern void DIVA_DIDD_Read(DESCRIPTOR *, int);
61
62/*
63 * debug
64 */
65static void no_printf(unsigned char *, ...);
66#include "debuglib.c"
67static void xlog(char *x, ...)
68{
69#ifndef DIVA_NO_DEBUGLIB
70 va_list ap;
71 if (myDriverDebugHandle.dbgMask & DL_XLOG) {
72 va_start(ap, x);
73 if (myDriverDebugHandle.dbg_irq) {
74 myDriverDebugHandle.dbg_irq(myDriverDebugHandle.id,
75 DLI_XLOG, x, ap);
76 } else if (myDriverDebugHandle.dbg_old) {
77 myDriverDebugHandle.dbg_old(myDriverDebugHandle.id,
78 x, ap);
79 }
80 va_end(ap);
81 }
82#endif
83}
84
85/*
86 * info for proc
87 */
88static char *diva_procinfo(struct capi_ctr *ctrl)
89{
90 return (ctrl->serial);
91}
92
93/*
94 * stop debugging
95 */
96static void stop_dbg(void)
97{
98 DbgDeregister();
99 memset(&MAdapter, 0, sizeof(MAdapter));
100 dprintf = no_printf;
101}
102
103/*
104 * dummy debug function
105 */
106static void no_printf(unsigned char *x, ...)
107{
108}
109
110/*
111 * Controller mapping
112 */
113byte MapController(byte Controller)
114{
115 byte i;
116 byte MappedController = 0;
117 byte ctrl = Controller & 0x7f; /* mask external controller bit off */
118
119 for (i = 1; i < max_adapter + 1; i++) {
120 if (ctrl == ControllerMap[i]) {
121 MappedController = (byte) i;
122 break;
123 }
124 }
125 if (i > max_adapter) {
126 ControllerMap[0] = ctrl;
127 MappedController = 0;
128 }
129 return (MappedController | (Controller & 0x80)); /* put back external controller bit */
130}
131
132/*
133 * Controller unmapping
134 */
135byte UnMapController(byte MappedController)
136{
137 byte Controller;
138 byte ctrl = MappedController & 0x7f; /* mask external controller bit off */
139
140 if (ctrl <= max_adapter) {
141 Controller = ControllerMap[ctrl];
142 } else {
143 Controller = 0;
144 }
145
146 return (Controller | (MappedController & 0x80)); /* put back external controller bit */
147}
148
149/*
150 * find a new free id
151 */
152static int find_free_id(void)
153{
154 int num = 0;
155 DIVA_CAPI_ADAPTER *a;
156
157 while (num < MAX_DESCRIPTORS) {
158 a = &adapter[num];
159 if (!a->Id)
160 break;
161 num++;
162 }
163 return (num + 1);
164}
165
166/*
167 * find a card structure by controller number
168 */
169static diva_card *find_card_by_ctrl(word controller)
170{
171 struct list_head *tmp;
172 diva_card *card;
173
174 list_for_each(tmp, &cards) {
175 card = list_entry(tmp, diva_card, list);
176 if (ControllerMap[card->Id] == controller) {
177 if (card->remove_in_progress)
178 card = NULL;
179 return (card);
180 }
181 }
182 return (diva_card *) 0;
183}
184
185/*
186 * Buffer RX/TX
187 */
188void *TransmitBufferSet(APPL *appl, dword ref)
189{
190 appl->xbuffer_used[ref] = true;
191 DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))
192 return (void *)(long)ref;
193}
194
195void *TransmitBufferGet(APPL *appl, void *p)
196{
197 if (appl->xbuffer_internal[(dword)(long)p])
198 return appl->xbuffer_internal[(dword)(long)p];
199
200 return appl->xbuffer_ptr[(dword)(long)p];
201}
202
203void TransmitBufferFree(APPL *appl, void *p)
204{
205 appl->xbuffer_used[(dword)(long)p] = false;
206 DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1))
207 }
208
209void *ReceiveBufferGet(APPL *appl, int Num)
210{
211 return &appl->ReceiveBuffer[Num * appl->MaxDataLength];
212}
213
214/*
215 * api_remove_start/complete for cleanup
216 */
217void api_remove_complete(void)
218{
219 DBG_PRV1(("api_remove_complete"))
220 }
221
222/*
223 * main function called by message.c
224 */
225void sendf(APPL *appl, word command, dword Id, word Number, byte *format, ...)
226{
227 word i, j;
228 word length = 12, dlength = 0;
229 byte *write;
230 CAPI_MSG msg;
231 byte *string = NULL;
232 va_list ap;
233 diva_os_message_buffer_s *dmb;
234 diva_card *card = NULL;
235 dword tmp;
236
237 if (!appl)
238 return;
239
240 DBG_PRV1(("sendf(a=%d,cmd=%x,format=%s)",
241 appl->Id, command, (byte *) format))
242
243 PUT_WORD(&msg.header.appl_id, appl->Id);
244 PUT_WORD(&msg.header.command, command);
245 if ((byte) (command >> 8) == 0x82)
246 Number = appl->Number++;
247 PUT_WORD(&msg.header.number, Number);
248
249 PUT_DWORD(&msg.header.controller, Id);
250 write = (byte *)&msg;
251 write += 12;
252
253 va_start(ap, format);
254 for (i = 0; format[i]; i++) {
255 switch (format[i]) {
256 case 'b':
257 tmp = va_arg(ap, dword);
258 *(byte *) write = (byte) (tmp & 0xff);
259 write += 1;
260 length += 1;
261 break;
262 case 'w':
263 tmp = va_arg(ap, dword);
264 PUT_WORD(write, (tmp & 0xffff));
265 write += 2;
266 length += 2;
267 break;
268 case 'd':
269 tmp = va_arg(ap, dword);
270 PUT_DWORD(write, tmp);
271 write += 4;
272 length += 4;
273 break;
274 case 's':
275 case 'S':
276 string = va_arg(ap, byte *);
277 length += string[0] + 1;
278 for (j = 0; j <= string[0]; j++)
279 *write++ = string[j];
280 break;
281 }
282 }
283 va_end(ap);
284
285 PUT_WORD(&msg.header.length, length);
286 msg.header.controller = UnMapController(msg.header.controller);
287
288 if (command == _DATA_B3_I)
289 dlength = GET_WORD(
290 ((byte *)&msg.info.data_b3_ind.Data_Length));
291
292 if (!(dmb = diva_os_alloc_message_buffer(length + dlength,
293 (void **) &write))) {
294 DBG_ERR(("sendf: alloc_message_buffer failed, incoming msg dropped."))
295 return;
296 }
297
298 /* copy msg header to sk_buff */
299 memcpy(write, (byte *)&msg, length);
300
301 /* if DATA_B3_IND, copy data too */
302 if (command == _DATA_B3_I) {
303 dword data = GET_DWORD(&msg.info.data_b3_ind.Data);
304 memcpy(write + length, (void *)(long)data, dlength);
305 }
306
307#ifndef DIVA_NO_DEBUGLIB
308 if (myDriverDebugHandle.dbgMask & DL_XLOG) {
309 switch (command) {
310 default:
311 xlog("\x00\x02", &msg, 0x81, length);
312 break;
313 case _DATA_B3_R | CONFIRM:
314 if (myDriverDebugHandle.dbgMask & DL_BLK)
315 xlog("\x00\x02", &msg, 0x81, length);
316 break;
317 case _DATA_B3_I:
318 if (myDriverDebugHandle.dbgMask & DL_BLK) {
319 xlog("\x00\x02", &msg, 0x81, length);
320 for (i = 0; i < dlength; i += 256) {
321 DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
322 ((dlength - i) < 256) ? (dlength - i) : 256))
323 if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
324 break; /* not more if not explicitly requested */
325 }
326 }
327 break;
328 }
329 }
330#endif
331
332 /* find the card structure for this controller */
333 if (!(card = find_card_by_ctrl(write[8] & 0x7f))) {
334 DBG_ERR(("sendf - controller %d not found, incoming msg dropped",
335 write[8] & 0x7f))
336 diva_os_free_message_buffer(dmb);
337 return;
338 }
339 /* send capi msg to capi layer */
340 capi_ctr_handle_message(&card->capi_ctrl, appl->Id, dmb);
341}
342
343/*
344 * cleanup adapter
345 */
346static void clean_adapter(int id, struct list_head *free_mem_q)
347{
348 DIVA_CAPI_ADAPTER *a;
349 int i, k;
350
351 a = &adapter[id];
352 k = li_total_channels - a->li_channels;
353 if (k == 0) {
354 if (li_config_table) {
355 list_add((struct list_head *)li_config_table, free_mem_q);
356 li_config_table = NULL;
357 }
358 } else {
359 if (a->li_base < k) {
360 memmove(&li_config_table[a->li_base],
361 &li_config_table[a->li_base + a->li_channels],
362 (k - a->li_base) * sizeof(LI_CONFIG));
363 for (i = 0; i < k; i++) {
364 memmove(&li_config_table[i].flag_table[a->li_base],
365 &li_config_table[i].flag_table[a->li_base + a->li_channels],
366 k - a->li_base);
367 memmove(&li_config_table[i].
368 coef_table[a->li_base],
369 &li_config_table[i].coef_table[a->li_base + a->li_channels],
370 k - a->li_base);
371 }
372 }
373 }
374 li_total_channels = k;
375 for (i = id; i < max_adapter; i++) {
376 if (adapter[i].request)
377 adapter[i].li_base -= a->li_channels;
378 }
379 if (a->plci)
380 list_add((struct list_head *)a->plci, free_mem_q);
381
382 memset(a, 0x00, sizeof(DIVA_CAPI_ADAPTER));
383 while ((max_adapter != 0) && !adapter[max_adapter - 1].request)
384 max_adapter--;
385}
386
387/*
388 * remove a card, but ensures consistent state of LI tables
389 * in the time adapter is removed
390 */
391static void divacapi_remove_card(DESCRIPTOR *d)
392{
393 diva_card *card = NULL;
394 diva_os_spin_lock_magic_t old_irql;
395 LIST_HEAD(free_mem_q);
396 struct list_head *link;
397 struct list_head *tmp;
398
399 /*
400 * Set "remove in progress flag".
401 * Ensures that there is no call from sendf to CAPI in
402 * the time CAPI controller is about to be removed.
403 */
404 diva_os_enter_spin_lock(&api_lock, &old_irql, "remove card");
405 list_for_each(tmp, &cards) {
406 card = list_entry(tmp, diva_card, list);
407 if (card->d.request == d->request) {
408 card->remove_in_progress = 1;
409 list_del(tmp);
410 break;
411 }
412 }
413 diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card");
414
415 if (card) {
416 /*
417 * Detach CAPI. Sendf cannot call to CAPI any more.
418 * After detach no call to send_message() is done too.
419 */
420 detach_capi_ctr(&card->capi_ctrl);
421
422 /*
423 * Now get API lock (to ensure stable state of LI tables)
424 * and update the adapter map/LI table.
425 */
426 diva_os_enter_spin_lock(&api_lock, &old_irql, "remove card");
427
428 clean_adapter(card->Id - 1, &free_mem_q);
429 DBG_TRC(("DelAdapterMap (%d) -> (%d)",
430 ControllerMap[card->Id], card->Id))
431 ControllerMap[card->Id] = 0;
432 DBG_TRC(("adapter remove, max_adapter=%d",
433 max_adapter));
434 diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card");
435
436 /* After releasing the lock, we can free the memory */
437 diva_os_free(0, card);
438 }
439
440 /* free queued memory areas */
441 list_for_each_safe(link, tmp, &free_mem_q) {
442 list_del(link);
443 diva_os_free(0, link);
444 }
445}
446
447/*
448 * remove cards
449 */
450static void divacapi_remove_cards(void)
451{
452 DESCRIPTOR d;
453 struct list_head *tmp;
454 diva_card *card;
455 diva_os_spin_lock_magic_t old_irql;
456
457rescan:
458 diva_os_enter_spin_lock(&api_lock, &old_irql, "remove cards");
459 list_for_each(tmp, &cards) {
460 card = list_entry(tmp, diva_card, list);
461 diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards");
462 d.request = card->d.request;
463 divacapi_remove_card(&d);
464 goto rescan;
465 }
466 diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards");
467}
468
469/*
470 * sync_callback
471 */
472static void sync_callback(ENTITY *e)
473{
474 diva_os_spin_lock_magic_t old_irql;
475
476 DBG_TRC(("cb:Id=%x,Rc=%x,Ind=%x", e->Id, e->Rc, e->Ind))
477
478 diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback");
479 callback(e);
480 diva_os_leave_spin_lock(&api_lock, &old_irql, "sync_callback");
481}
482
483/*
484 * add a new card
485 */
486static int diva_add_card(DESCRIPTOR *d)
487{
488 int k = 0, i = 0;
489 diva_os_spin_lock_magic_t old_irql;
490 diva_card *card = NULL;
491 struct capi_ctr *ctrl = NULL;
492 DIVA_CAPI_ADAPTER *a = NULL;
493 IDI_SYNC_REQ sync_req;
494 char serial[16];
495 void *mem_to_free;
496 LI_CONFIG *new_li_config_table;
497 int j;
498
499 if (!(card = (diva_card *) diva_os_malloc(0, sizeof(diva_card)))) {
500 DBG_ERR(("diva_add_card: failed to allocate card struct."))
501 return (0);
502 }
503 memset((char *) card, 0x00, sizeof(diva_card));
504 memcpy(&card->d, d, sizeof(DESCRIPTOR));
505 sync_req.GetName.Req = 0;
506 sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME;
507 card->d.request((ENTITY *)&sync_req);
508 strlcpy(card->name, sync_req.GetName.name, sizeof(card->name));
509 ctrl = &card->capi_ctrl;
510 strcpy(ctrl->name, card->name);
511 ctrl->register_appl = diva_register_appl;
512 ctrl->release_appl = diva_release_appl;
513 ctrl->send_message = diva_send_message;
514 ctrl->procinfo = diva_procinfo;
515 ctrl->driverdata = card;
516 diva_os_set_controller_struct(ctrl);
517
518 if (attach_capi_ctr(ctrl)) {
519 DBG_ERR(("diva_add_card: failed to attach controller."))
520 diva_os_free(0, card);
521 return (0);
522 }
523
524 diva_os_enter_spin_lock(&api_lock, &old_irql, "find id");
525 card->Id = find_free_id();
526 diva_os_leave_spin_lock(&api_lock, &old_irql, "find id");
527
528 strlcpy(ctrl->manu, M_COMPANY, sizeof(ctrl->manu));
529 ctrl->version.majorversion = 2;
530 ctrl->version.minorversion = 0;
531 ctrl->version.majormanuversion = DRRELMAJOR;
532 ctrl->version.minormanuversion = DRRELMINOR;
533 sync_req.GetSerial.Req = 0;
534 sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
535 sync_req.GetSerial.serial = 0;
536 card->d.request((ENTITY *)&sync_req);
537 if ((i = ((sync_req.GetSerial.serial & 0xff000000) >> 24))) {
538 sprintf(serial, "%ld-%d",
539 sync_req.GetSerial.serial & 0x00ffffff, i + 1);
540 } else {
541 sprintf(serial, "%ld", sync_req.GetSerial.serial);
542 }
543 serial[CAPI_SERIAL_LEN - 1] = 0;
544 strlcpy(ctrl->serial, serial, sizeof(ctrl->serial));
545
546 a = &adapter[card->Id - 1];
547 card->adapter = a;
548 a->os_card = card;
549 ControllerMap[card->Id] = (byte) (ctrl->cnr);
550
551 DBG_TRC(("AddAdapterMap (%d) -> (%d)", ctrl->cnr, card->Id))
552
553 sync_req.xdi_capi_prms.Req = 0;
554 sync_req.xdi_capi_prms.Rc = IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS;
555 sync_req.xdi_capi_prms.info.structure_length =
556 sizeof(diva_xdi_get_capi_parameters_t);
557 card->d.request((ENTITY *)&sync_req);
558 a->flag_dynamic_l1_down =
559 sync_req.xdi_capi_prms.info.flag_dynamic_l1_down;
560 a->group_optimization_enabled =
561 sync_req.xdi_capi_prms.info.group_optimization_enabled;
562 a->request = DIRequest; /* card->d.request; */
563 a->max_plci = card->d.channels + 30;
564 a->max_listen = (card->d.channels > 2) ? 8 : 2;
565 if (!
566 (a->plci =
567 (PLCI *) diva_os_malloc(0, sizeof(PLCI) * a->max_plci))) {
568 DBG_ERR(("diva_add_card: failed alloc plci struct."))
569 memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
570 return (0);
571 }
572 memset(a->plci, 0, sizeof(PLCI) * a->max_plci);
573
574 for (k = 0; k < a->max_plci; k++) {
575 a->Id = (byte) card->Id;
576 a->plci[k].Sig.callback = sync_callback;
577 a->plci[k].Sig.XNum = 1;
578 a->plci[k].Sig.X = a->plci[k].XData;
579 a->plci[k].Sig.user[0] = (word) (card->Id - 1);
580 a->plci[k].Sig.user[1] = (word) k;
581 a->plci[k].NL.callback = sync_callback;
582 a->plci[k].NL.XNum = 1;
583 a->plci[k].NL.X = a->plci[k].XData;
584 a->plci[k].NL.user[0] = (word) ((card->Id - 1) | 0x8000);
585 a->plci[k].NL.user[1] = (word) k;
586 a->plci[k].adapter = a;
587 }
588
589 a->profile.Number = card->Id;
590 a->profile.Channels = card->d.channels;
591 if (card->d.features & DI_FAX3) {
592 a->profile.Global_Options = 0x71;
593 if (card->d.features & DI_CODEC)
594 a->profile.Global_Options |= 0x6;
595#if IMPLEMENT_DTMF
596 a->profile.Global_Options |= 0x8;
597#endif /* IMPLEMENT_DTMF */
598 a->profile.Global_Options |= 0x80; /* Line Interconnect */
599#if IMPLEMENT_ECHO_CANCELLER
600 a->profile.Global_Options |= 0x100;
601#endif /* IMPLEMENT_ECHO_CANCELLER */
602 a->profile.B1_Protocols = 0xdf;
603 a->profile.B2_Protocols = 0x1fdb;
604 a->profile.B3_Protocols = 0xb7;
605 a->manufacturer_features = MANUFACTURER_FEATURE_HARDDTMF;
606 } else {
607 a->profile.Global_Options = 0x71;
608 if (card->d.features & DI_CODEC)
609 a->profile.Global_Options |= 0x2;
610 a->profile.B1_Protocols = 0x43;
611 a->profile.B2_Protocols = 0x1f0f;
612 a->profile.B3_Protocols = 0x07;
613 a->manufacturer_features = 0;
614 }
615
616 a->li_pri = (a->profile.Channels > 2);
617 a->li_channels = a->li_pri ? MIXER_CHANNELS_PRI : MIXER_CHANNELS_BRI;
618 a->li_base = 0;
619 for (i = 0; &adapter[i] != a; i++) {
620 if (adapter[i].request)
621 a->li_base = adapter[i].li_base + adapter[i].li_channels;
622 }
623 k = li_total_channels + a->li_channels;
624 new_li_config_table =
625 (LI_CONFIG *) diva_os_malloc(0, ((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * k) * ((k + 3) & ~3));
626 if (new_li_config_table == NULL) {
627 DBG_ERR(("diva_add_card: failed alloc li_config table."))
628 memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
629 return (0);
630 }
631
632 /* Prevent access to line interconnect table in process update */
633 diva_os_enter_spin_lock(&api_lock, &old_irql, "add card");
634
635 j = 0;
636 for (i = 0; i < k; i++) {
637 if ((i >= a->li_base) && (i < a->li_base + a->li_channels))
638 memset(&new_li_config_table[i], 0, sizeof(LI_CONFIG));
639 else
640 memcpy(&new_li_config_table[i], &li_config_table[j], sizeof(LI_CONFIG));
641 new_li_config_table[i].flag_table =
642 ((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i) * ((k + 3) & ~3));
643 new_li_config_table[i].coef_table =
644 ((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i + 1) * ((k + 3) & ~3));
645 if ((i >= a->li_base) && (i < a->li_base + a->li_channels)) {
646 new_li_config_table[i].adapter = a;
647 memset(&new_li_config_table[i].flag_table[0], 0, k);
648 memset(&new_li_config_table[i].coef_table[0], 0, k);
649 } else {
650 if (a->li_base != 0) {
651 memcpy(&new_li_config_table[i].flag_table[0],
652 &li_config_table[j].flag_table[0],
653 a->li_base);
654 memcpy(&new_li_config_table[i].coef_table[0],
655 &li_config_table[j].coef_table[0],
656 a->li_base);
657 }
658 memset(&new_li_config_table[i].flag_table[a->li_base], 0, a->li_channels);
659 memset(&new_li_config_table[i].coef_table[a->li_base], 0, a->li_channels);
660 if (a->li_base + a->li_channels < k) {
661 memcpy(&new_li_config_table[i].flag_table[a->li_base +
662 a->li_channels],
663 &li_config_table[j].flag_table[a->li_base],
664 k - (a->li_base + a->li_channels));
665 memcpy(&new_li_config_table[i].coef_table[a->li_base +
666 a->li_channels],
667 &li_config_table[j].coef_table[a->li_base],
668 k - (a->li_base + a->li_channels));
669 }
670 j++;
671 }
672 }
673 li_total_channels = k;
674
675 mem_to_free = li_config_table;
676
677 li_config_table = new_li_config_table;
678 for (i = card->Id; i < max_adapter; i++) {
679 if (adapter[i].request)
680 adapter[i].li_base += a->li_channels;
681 }
682
683 if (a == &adapter[max_adapter])
684 max_adapter++;
685
686 list_add(&(card->list), &cards);
687 AutomaticLaw(a);
688
689 diva_os_leave_spin_lock(&api_lock, &old_irql, "add card");
690
691 if (mem_to_free) {
692 diva_os_free(0, mem_to_free);
693 }
694
695 i = 0;
696 while (i++ < 30) {
697 if (a->automatic_law > 3)
698 break;
699 diva_os_sleep(10);
700 }
701
702 /* profile information */
703 PUT_WORD(&ctrl->profile.nbchannel, card->d.channels);
704 ctrl->profile.goptions = a->profile.Global_Options;
705 ctrl->profile.support1 = a->profile.B1_Protocols;
706 ctrl->profile.support2 = a->profile.B2_Protocols;
707 ctrl->profile.support3 = a->profile.B3_Protocols;
708 /* manufacturer profile information */
709 ctrl->profile.manu[0] = a->man_profile.private_options;
710 ctrl->profile.manu[1] = a->man_profile.rtp_primary_payloads;
711 ctrl->profile.manu[2] = a->man_profile.rtp_additional_payloads;
712 ctrl->profile.manu[3] = 0;
713 ctrl->profile.manu[4] = 0;
714
715 capi_ctr_ready(ctrl);
716
717 DBG_TRC(("adapter added, max_adapter=%d", max_adapter));
718 return (1);
719}
720
721/*
722 * register appl
723 */
724static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
725 capi_register_params *rp)
726{
727 APPL *this;
728 word bnum, xnum;
729 int i = 0;
730 unsigned char *p;
731 void *DataNCCI, *DataFlags, *ReceiveBuffer, *xbuffer_used;
732 void **xbuffer_ptr, **xbuffer_internal;
733 diva_os_spin_lock_magic_t old_irql;
734 unsigned int mem_len;
735 int nconn = rp->level3cnt;
736
737
738 if (diva_os_in_irq()) {
739 DBG_ERR(("CAPI_REGISTER - in irq context !"))
740 return;
741 }
742
743 DBG_TRC(("application register Id=%d", appl))
744
745 if (appl > MAX_APPL) {
746 DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))
747 return;
748 }
749
750 if (nconn <= 0)
751 nconn = ctrl->profile.nbchannel * -nconn;
752
753 if (nconn == 0)
754 nconn = ctrl->profile.nbchannel;
755
756 DBG_LOG(("CAPI_REGISTER - Id = %d", appl))
757 DBG_LOG((" MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt))
758 DBG_LOG((" MaxBDataBuffers = %d", rp->datablkcnt))
759 DBG_LOG((" MaxBDataLength = %d", rp->datablklen))
760
761 if (nconn < 1 ||
762 nconn > 255 ||
763 rp->datablklen < 80 ||
764 rp->datablklen > 2150 || rp->datablkcnt > 255) {
765 DBG_ERR(("CAPI_REGISTER - invalid parameters"))
766 return;
767 }
768
769 if (application[appl - 1].Id == appl) {
770 DBG_LOG(("CAPI_REGISTER - appl already registered"))
771 return; /* appl already registered */
772 }
773
774 /* alloc memory */
775
776 bnum = nconn * rp->datablkcnt;
777 xnum = nconn * MAX_DATA_B3;
778
779 mem_len = bnum * sizeof(word); /* DataNCCI */
780 mem_len += bnum * sizeof(word); /* DataFlags */
781 mem_len += bnum * rp->datablklen; /* ReceiveBuffer */
782 mem_len += xnum; /* xbuffer_used */
783 mem_len += xnum * sizeof(void *); /* xbuffer_ptr */
784 mem_len += xnum * sizeof(void *); /* xbuffer_internal */
785 mem_len += xnum * rp->datablklen; /* xbuffer_ptr[xnum] */
786
787 DBG_LOG((" Allocated Memory = %d", mem_len))
788 if (!(p = diva_os_malloc(0, mem_len))) {
789 DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
790 return;
791 }
792 memset(p, 0, mem_len);
793
794 DataNCCI = (void *)p;
795 p += bnum * sizeof(word);
796 DataFlags = (void *)p;
797 p += bnum * sizeof(word);
798 ReceiveBuffer = (void *)p;
799 p += bnum * rp->datablklen;
800 xbuffer_used = (void *)p;
801 p += xnum;
802 xbuffer_ptr = (void **)p;
803 p += xnum * sizeof(void *);
804 xbuffer_internal = (void **)p;
805 p += xnum * sizeof(void *);
806 for (i = 0; i < xnum; i++) {
807 xbuffer_ptr[i] = (void *)p;
808 p += rp->datablklen;
809 }
810
811 /* initialize application data */
812 diva_os_enter_spin_lock(&api_lock, &old_irql, "register_appl");
813
814 this = &application[appl - 1];
815 memset(this, 0, sizeof(APPL));
816
817 this->Id = appl;
818
819 for (i = 0; i < max_adapter; i++) {
820 adapter[i].CIP_Mask[appl - 1] = 0;
821 }
822
823 this->queue_size = 1000;
824
825 this->MaxNCCI = (byte) nconn;
826 this->MaxNCCIData = (byte) rp->datablkcnt;
827 this->MaxBuffer = bnum;
828 this->MaxDataLength = rp->datablklen;
829
830 this->DataNCCI = DataNCCI;
831 this->DataFlags = DataFlags;
832 this->ReceiveBuffer = ReceiveBuffer;
833 this->xbuffer_used = xbuffer_used;
834 this->xbuffer_ptr = xbuffer_ptr;
835 this->xbuffer_internal = xbuffer_internal;
836 for (i = 0; i < xnum; i++) {
837 this->xbuffer_ptr[i] = xbuffer_ptr[i];
838 }
839
840 CapiRegister(this->Id);
841 diva_os_leave_spin_lock(&api_lock, &old_irql, "register_appl");
842
843}
844
845/*
846 * release appl
847 */
848static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl)
849{
850 diva_os_spin_lock_magic_t old_irql;
851 APPL *this = &application[appl - 1];
852 void *mem_to_free = NULL;
853
854 DBG_TRC(("application %d(%d) cleanup", this->Id, appl))
855
856 if (diva_os_in_irq()) {
857 DBG_ERR(("CAPI_RELEASE - in irq context !"))
858 return;
859 }
860
861 diva_os_enter_spin_lock(&api_lock, &old_irql, "release_appl");
862 if (this->Id) {
863 CapiRelease(this->Id);
864 mem_to_free = this->DataNCCI;
865 this->DataNCCI = NULL;
866 this->Id = 0;
867 }
868 diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl");
869
870 if (mem_to_free)
871 diva_os_free(0, mem_to_free);
872
873}
874
875/*
876 * send message
877 */
878static u16 diva_send_message(struct capi_ctr *ctrl,
879 diva_os_message_buffer_s *dmb)
880{
881 int i = 0;
882 word ret = 0;
883 diva_os_spin_lock_magic_t old_irql;
884 CAPI_MSG *msg = (CAPI_MSG *) DIVA_MESSAGE_BUFFER_DATA(dmb);
885 APPL *this = &application[GET_WORD(&msg->header.appl_id) - 1];
886 diva_card *card = ctrl->driverdata;
887 __u32 length = DIVA_MESSAGE_BUFFER_LEN(dmb);
888 word clength = GET_WORD(&msg->header.length);
889 word command = GET_WORD(&msg->header.command);
890 u16 retval = CAPI_NOERROR;
891
892 if (diva_os_in_irq()) {
893 DBG_ERR(("CAPI_SEND_MSG - in irq context !"))
894 return CAPI_REGOSRESOURCEERR;
895 }
896 DBG_PRV1(("Write - appl = %d, cmd = 0x%x", this->Id, command))
897
898 if (card->remove_in_progress) {
899 DBG_ERR(("CAPI_SEND_MSG - remove in progress!"))
900 return CAPI_REGOSRESOURCEERR;
901 }
902
903 diva_os_enter_spin_lock(&api_lock, &old_irql, "send message");
904
905 if (!this->Id) {
906 diva_os_leave_spin_lock(&api_lock, &old_irql, "send message");
907 return CAPI_ILLAPPNR;
908 }
909
910 /* patch controller number */
911 msg->header.controller = ControllerMap[card->Id]
912 | (msg->header.controller & 0x80); /* preserve external controller bit */
913
914 switch (command) {
915 default:
916 xlog("\x00\x02", msg, 0x80, clength);
917 break;
918
919 case _DATA_B3_I | RESPONSE:
920#ifndef DIVA_NO_DEBUGLIB
921 if (myDriverDebugHandle.dbgMask & DL_BLK)
922 xlog("\x00\x02", msg, 0x80, clength);
923#endif
924 break;
925
926 case _DATA_B3_R:
927#ifndef DIVA_NO_DEBUGLIB
928 if (myDriverDebugHandle.dbgMask & DL_BLK)
929 xlog("\x00\x02", msg, 0x80, clength);
930#endif
931
932 if (clength == 24)
933 clength = 22; /* workaround for PPcom bug */
934 /* header is always 22 */
935 if (GET_WORD(&msg->info.data_b3_req.Data_Length) >
936 this->MaxDataLength
937 || GET_WORD(&msg->info.data_b3_req.Data_Length) >
938 (length - clength)) {
939 DBG_ERR(("Write - invalid message size"))
940 retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
941 goto write_end;
942 }
943
944 for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI)
945 && this->xbuffer_used[i]; i++);
946 if (i == (MAX_DATA_B3 * this->MaxNCCI)) {
947 DBG_ERR(("Write - too many data pending"))
948 retval = CAPI_SENDQUEUEFULL;
949 goto write_end;
950 }
951 msg->info.data_b3_req.Data = i;
952
953 this->xbuffer_internal[i] = NULL;
954 memcpy(this->xbuffer_ptr[i], &((__u8 *) msg)[clength],
955 GET_WORD(&msg->info.data_b3_req.Data_Length));
956
957#ifndef DIVA_NO_DEBUGLIB
958 if ((myDriverDebugHandle.dbgMask & DL_BLK)
959 && (myDriverDebugHandle.dbgMask & DL_XLOG)) {
960 int j;
961 for (j = 0; j <
962 GET_WORD(&msg->info.data_b3_req.Data_Length);
963 j += 256) {
964 DBG_BLK((((char *) this->xbuffer_ptr[i]) + j,
965 ((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) <
966 256) ? (GET_WORD(&msg->info.data_b3_req.Data_Length) - j) : 256))
967 if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
968 break; /* not more if not explicitly requested */
969 }
970 }
971#endif
972 break;
973 }
974
975 memcpy(mapped_msg, msg, (__u32) clength);
976 mapped_msg->header.controller = MapController(mapped_msg->header.controller);
977 mapped_msg->header.length = clength;
978 mapped_msg->header.command = command;
979 mapped_msg->header.number = GET_WORD(&msg->header.number);
980
981 ret = api_put(this, mapped_msg);
982 switch (ret) {
983 case 0:
984 break;
985 case _BAD_MSG:
986 DBG_ERR(("Write - bad message"))
987 retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
988 break;
989 case _QUEUE_FULL:
990 DBG_ERR(("Write - queue full"))
991 retval = CAPI_SENDQUEUEFULL;
992 break;
993 default:
994 DBG_ERR(("Write - api_put returned unknown error"))
995 retval = CAPI_UNKNOWNNOTPAR;
996 break;
997 }
998
999write_end:
1000 diva_os_leave_spin_lock(&api_lock, &old_irql, "send message");
1001 if (retval == CAPI_NOERROR)
1002 diva_os_free_message_buffer(dmb);
1003 return retval;
1004}
1005
1006
1007/*
1008 * cards request function
1009 */
1010static void DIRequest(ENTITY *e)
1011{
1012 DIVA_CAPI_ADAPTER *a = &(adapter[(byte) e->user[0]]);
1013 diva_card *os_card = (diva_card *) a->os_card;
1014
1015 if (e->Req && (a->FlowControlIdTable[e->ReqCh] == e->Id)) {
1016 a->FlowControlSkipTable[e->ReqCh] = 1;
1017 }
1018
1019 (*(os_card->d.request)) (e);
1020}
1021
1022/*
1023 * callback function from didd
1024 */
1025static void didd_callback(void *context, DESCRIPTOR *adapter, int removal)
1026{
1027 if (adapter->type == IDI_DADAPTER) {
1028 DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
1029 return;
1030 } else if (adapter->type == IDI_DIMAINT) {
1031 if (removal) {
1032 stop_dbg();
1033 } else {
1034 memcpy(&MAdapter, adapter, sizeof(MAdapter));
1035 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
1036 DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
1037 }
1038 } else if ((adapter->type > 0) && (adapter->type < 16)) { /* IDI Adapter */
1039 if (removal) {
1040 divacapi_remove_card(adapter);
1041 } else {
1042 diva_add_card(adapter);
1043 }
1044 }
1045 return;
1046}
1047
1048/*
1049 * connect to didd
1050 */
1051static int divacapi_connect_didd(void)
1052{
1053 int x = 0;
1054 int dadapter = 0;
1055 IDI_SYNC_REQ req;
1056 DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
1057
1058 DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
1059
1060 for (x = 0; x < MAX_DESCRIPTORS; x++) {
1061 if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
1062 memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
1063 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
1064 DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
1065 break;
1066 }
1067 }
1068 for (x = 0; x < MAX_DESCRIPTORS; x++) {
1069 if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */
1070 dadapter = 1;
1071 memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
1072 req.didd_notify.e.Req = 0;
1073 req.didd_notify.e.Rc =
1074 IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
1075 req.didd_notify.info.callback = (void *)didd_callback;
1076 req.didd_notify.info.context = NULL;
1077 DAdapter.request((ENTITY *)&req);
1078 if (req.didd_notify.e.Rc != 0xff) {
1079 stop_dbg();
1080 return (0);
1081 }
1082 notify_handle = req.didd_notify.info.handle;
1083 }
1084 else if ((DIDD_Table[x].type > 0) && (DIDD_Table[x].type < 16)) { /* IDI Adapter found */
1085 diva_add_card(&DIDD_Table[x]);
1086 }
1087 }
1088
1089 if (!dadapter) {
1090 stop_dbg();
1091 }
1092
1093 return (dadapter);
1094}
1095
1096/*
1097 * diconnect from didd
1098 */
1099static void divacapi_disconnect_didd(void)
1100{
1101 IDI_SYNC_REQ req;
1102
1103 stop_dbg();
1104
1105 req.didd_notify.e.Req = 0;
1106 req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
1107 req.didd_notify.info.handle = notify_handle;
1108 DAdapter.request((ENTITY *)&req);
1109}
1110
1111/*
1112 * we do not provide date/time here,
1113 * the application should do this.
1114 */
1115int fax_head_line_time(char *buffer)
1116{
1117 return (0);
1118}
1119
1120/*
1121 * init (alloc) main structures
1122 */
1123static int __init init_main_structs(void)
1124{
1125 if (!(mapped_msg = (CAPI_MSG *) diva_os_malloc(0, MAX_MSG_SIZE))) {
1126 DBG_ERR(("init: failed alloc mapped_msg."))
1127 return 0;
1128 }
1129
1130 if (!(adapter = diva_os_malloc(0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS))) {
1131 DBG_ERR(("init: failed alloc adapter struct."))
1132 diva_os_free(0, mapped_msg);
1133 return 0;
1134 }
1135 memset(adapter, 0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS);
1136
1137 if (!(application = diva_os_malloc(0, sizeof(APPL) * MAX_APPL))) {
1138 DBG_ERR(("init: failed alloc application struct."))
1139 diva_os_free(0, mapped_msg);
1140 diva_os_free(0, adapter);
1141 return 0;
1142 }
1143 memset(application, 0, sizeof(APPL) * MAX_APPL);
1144
1145 return (1);
1146}
1147
1148/*
1149 * remove (free) main structures
1150 */
1151static void remove_main_structs(void)
1152{
1153 if (application)
1154 diva_os_free(0, application);
1155 if (adapter)
1156 diva_os_free(0, adapter);
1157 if (mapped_msg)
1158 diva_os_free(0, mapped_msg);
1159}
1160
1161/*
1162 * api_remove_start
1163 */
1164static void do_api_remove_start(void)
1165{
1166 diva_os_spin_lock_magic_t old_irql;
1167 int ret = 1, count = 100;
1168
1169 do {
1170 diva_os_enter_spin_lock(&api_lock, &old_irql, "api remove start");
1171 ret = api_remove_start();
1172 diva_os_leave_spin_lock(&api_lock, &old_irql, "api remove start");
1173
1174 diva_os_sleep(10);
1175 } while (ret && count--);
1176
1177 if (ret)
1178 DBG_ERR(("could not remove signaling ID's"))
1179 }
1180
1181/*
1182 * init
1183 */
1184int __init init_capifunc(void)
1185{
1186 diva_os_initialize_spin_lock(&api_lock, "capifunc");
1187 memset(ControllerMap, 0, MAX_DESCRIPTORS + 1);
1188 max_adapter = 0;
1189
1190
1191 if (!init_main_structs()) {
1192 DBG_ERR(("init: failed to init main structs."))
1193 diva_os_destroy_spin_lock(&api_lock, "capifunc");
1194 return (0);
1195 }
1196
1197 if (!divacapi_connect_didd()) {
1198 DBG_ERR(("init: failed to connect to DIDD."))
1199 do_api_remove_start();
1200 divacapi_remove_cards();
1201 remove_main_structs();
1202 diva_os_destroy_spin_lock(&api_lock, "capifunc");
1203 return (0);
1204 }
1205
1206 return (1);
1207}
1208
1209/*
1210 * finit
1211 */
1212void __exit finit_capifunc(void)
1213{
1214 do_api_remove_start();
1215 divacapi_disconnect_didd();
1216 divacapi_remove_cards();
1217 remove_main_structs();
1218 diva_os_destroy_spin_lock(&api_lock, "capifunc");
1219}
diff --git a/drivers/isdn/hardware/eicon/capifunc.h b/drivers/isdn/hardware/eicon/capifunc.h
deleted file mode 100644
index e96c45bb5638..000000000000
--- a/drivers/isdn/hardware/eicon/capifunc.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/* $Id: capifunc.h,v 1.11.4.1 2004/08/28 20:03:53 armin Exp $
2 *
3 * ISDN interface module for Eicon active cards DIVA.
4 * CAPI Interface common functions
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#ifndef __CAPIFUNC_H__
14#define __CAPIFUNC_H__
15
16#define DRRELMAJOR 2
17#define DRRELMINOR 0
18#define DRRELEXTRA ""
19
20#define M_COMPANY "Eicon Networks"
21
22extern char DRIVERRELEASE_CAPI[];
23
24typedef struct _diva_card {
25 struct list_head list;
26 int remove_in_progress;
27 int Id;
28 struct capi_ctr capi_ctrl;
29 DIVA_CAPI_ADAPTER *adapter;
30 DESCRIPTOR d;
31 char name[32];
32} diva_card;
33
34/*
35 * prototypes
36 */
37int init_capifunc(void);
38void finit_capifunc(void);
39
40#endif /* __CAPIFUNC_H__ */
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
deleted file mode 100644
index f9244dc1c3c9..000000000000
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ /dev/null
@@ -1,141 +0,0 @@
1/* $Id: capimain.c,v 1.24 2003/09/09 06:51:05 schindler Exp $
2 *
3 * ISDN interface module for Eicon active cards DIVA.
4 * CAPI Interface
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/uaccess.h>
17#include <linux/seq_file.h>
18#include <linux/skbuff.h>
19
20#include "os_capi.h"
21
22#include "platform.h"
23#include "di_defs.h"
24#include "capi20.h"
25#include "divacapi.h"
26#include "cp_vers.h"
27#include "capifunc.h"
28
29static char *main_revision = "$Revision: 1.24 $";
30static char *DRIVERNAME =
31 "Eicon DIVA - CAPI Interface driver (http://www.melware.net)";
32static char *DRIVERLNAME = "divacapi";
33
34MODULE_DESCRIPTION("CAPI driver for Eicon DIVA cards");
35MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
36MODULE_SUPPORTED_DEVICE("CAPI and DIVA card drivers");
37MODULE_LICENSE("GPL");
38
39/*
40 * get revision number from revision string
41 */
42static char *getrev(const char *revision)
43{
44 char *rev;
45 char *p;
46 if ((p = strchr(revision, ':'))) {
47 rev = p + 2;
48 p = strchr(rev, '$');
49 *--p = 0;
50 } else
51 rev = "1.0";
52 return rev;
53
54}
55
56/*
57 * alloc a message buffer
58 */
59diva_os_message_buffer_s *diva_os_alloc_message_buffer(unsigned long size,
60 void **data_buf)
61{
62 diva_os_message_buffer_s *dmb = alloc_skb(size, GFP_ATOMIC);
63 if (dmb) {
64 *data_buf = skb_put(dmb, size);
65 }
66 return (dmb);
67}
68
69/*
70 * free a message buffer
71 */
72void diva_os_free_message_buffer(diva_os_message_buffer_s *dmb)
73{
74 kfree_skb(dmb);
75}
76
77/*
78 * proc function for controller info
79 */
80static int diva_ctl_proc_show(struct seq_file *m, void *v)
81{
82 struct capi_ctr *ctrl = m->private;
83 diva_card *card = (diva_card *) ctrl->driverdata;
84
85 seq_printf(m, "%s\n", ctrl->name);
86 seq_printf(m, "Serial No. : %s\n", ctrl->serial);
87 seq_printf(m, "Id : %d\n", card->Id);
88 seq_printf(m, "Channels : %d\n", card->d.channels);
89
90 return 0;
91}
92
93/*
94 * set additional os settings in capi_ctr struct
95 */
96void diva_os_set_controller_struct(struct capi_ctr *ctrl)
97{
98 ctrl->driver_name = DRIVERLNAME;
99 ctrl->load_firmware = NULL;
100 ctrl->reset_ctr = NULL;
101 ctrl->proc_show = diva_ctl_proc_show;
102 ctrl->owner = THIS_MODULE;
103}
104
105/*
106 * module init
107 */
108static int __init divacapi_init(void)
109{
110 char tmprev[32];
111 int ret = 0;
112
113 sprintf(DRIVERRELEASE_CAPI, "%d.%d%s", DRRELMAJOR, DRRELMINOR,
114 DRRELEXTRA);
115
116 printk(KERN_INFO "%s\n", DRIVERNAME);
117 printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_CAPI);
118 strcpy(tmprev, main_revision);
119 printk("%s Build: %s(%s)\n", getrev(tmprev),
120 diva_capi_common_code_build, DIVA_BUILD);
121
122 if (!(init_capifunc())) {
123 printk(KERN_ERR "%s: failed init capi_driver.\n",
124 DRIVERLNAME);
125 ret = -EIO;
126 }
127
128 return ret;
129}
130
131/*
132 * module exit
133 */
134static void __exit divacapi_exit(void)
135{
136 finit_capifunc();
137 printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
138}
139
140module_init(divacapi_init);
141module_exit(divacapi_exit);
diff --git a/drivers/isdn/hardware/eicon/cardtype.h b/drivers/isdn/hardware/eicon/cardtype.h
deleted file mode 100644
index 8b20e22cae1e..000000000000
--- a/drivers/isdn/hardware/eicon/cardtype.h
+++ /dev/null
@@ -1,1098 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef _CARDTYPE_H_
27#define _CARDTYPE_H_
28#ifndef CARDTYPE_H_WANT_DATA
29#define CARDTYPE_H_WANT_DATA 0
30#endif
31#ifndef CARDTYPE_H_WANT_IDI_DATA
32#define CARDTYPE_H_WANT_IDI_DATA 0
33#endif
34#ifndef CARDTYPE_H_WANT_RESOURCE_DATA
35#define CARDTYPE_H_WANT_RESOURCE_DATA 1
36#endif
37#ifndef CARDTYPE_H_WANT_FILE_DATA
38#define CARDTYPE_H_WANT_FILE_DATA 1
39#endif
40/*
41 * D-channel protocol identifiers
42 *
43 * Attention: Unfortunately the identifiers defined here differ from
44 * the identifiers used in Protocol/1/Common/prot/q931.h .
45 * The only reason for this is that q931.h has not a global
46 * scope and we did not know about the definitions there.
47 * But the definitions here cannot be changed easily because
48 * they are used in setup scripts and programs.
49 * Thus the definitions here have to be mapped if they are
50 * used in the protocol code context !
51 *
52 * Now the identifiers are defined in the q931lib/constant.h file.
53 * Unfortunately this file has also not a global scope.
54 * But beginning with PROTTYPE_US any new identifier will get the same
55 * value as the corresponding PROT_* definition in q931lib/constant.h !
56 */
57#define PROTTYPE_MINVAL 0
58#define PROTTYPE_ETSI 0
59#define PROTTYPE_1TR6 1
60#define PROTTYPE_BELG 2
61#define PROTTYPE_FRANC 3
62#define PROTTYPE_ATEL 4
63#define PROTTYPE_NI 5 /* DMS 100, Nortel, National ISDN */
64#define PROTTYPE_5ESS 6 /* 5ESS , AT&T, 5ESS Custom */
65#define PROTTYPE_JAPAN 7
66#define PROTTYPE_SWED 8
67#define PROTTYPE_US 9 /* US autodetect */
68#define PROTTYPE_ITALY 10
69#define PROTTYPE_TWAN 11
70#define PROTTYPE_AUSTRAL 12
71#define PROTTYPE_4ESDN 13
72#define PROTTYPE_4ESDS 14
73#define PROTTYPE_4ELDS 15
74#define PROTTYPE_4EMGC 16
75#define PROTTYPE_4EMGI 17
76#define PROTTYPE_HONGKONG 18
77#define PROTTYPE_RBSCAS 19
78#define PROTTYPE_CORNETN 20
79#define PROTTYPE_QSIG 21
80#define PROTTYPE_NI_EWSD 22 /* EWSD, Siemens, National ISDN */
81#define PROTTYPE_5ESS_NI 23 /* 5ESS, Lucent, National ISDN */
82#define PROTTYPE_T1CORNETN 24
83#define PROTTYPE_CORNETNQ 25
84#define PROTTYPE_T1CORNETNQ 26
85#define PROTTYPE_T1QSIG 27
86#define PROTTYPE_E1UNCH 28
87#define PROTTYPE_T1UNCH 29
88#define PROTTYPE_E1CHAN 30
89#define PROTTYPE_T1CHAN 31
90#define PROTTYPE_R2CAS 32
91#define PROTTYPE_MAXVAL 32
92/*
93 * Card type identifiers
94 */
95#define CARD_UNKNOWN 0
96#define CARD_NONE 0
97/* DIVA cards */
98#define CARDTYPE_DIVA_MCA 0
99#define CARDTYPE_DIVA_ISA 1
100#define CARDTYPE_DIVA_PCM 2
101#define CARDTYPE_DIVAPRO_ISA 3
102#define CARDTYPE_DIVAPRO_PCM 4
103#define CARDTYPE_DIVAPICO_ISA 5
104#define CARDTYPE_DIVAPICO_PCM 6
105/* DIVA 2.0 cards */
106#define CARDTYPE_DIVAPRO20_PCI 7
107#define CARDTYPE_DIVA20_PCI 8
108/* S cards */
109#define CARDTYPE_QUADRO_ISA 9
110#define CARDTYPE_S_ISA 10
111#define CARDTYPE_S_MCA 11
112#define CARDTYPE_SX_ISA 12
113#define CARDTYPE_SX_MCA 13
114#define CARDTYPE_SXN_ISA 14
115#define CARDTYPE_SXN_MCA 15
116#define CARDTYPE_SCOM_ISA 16
117#define CARDTYPE_SCOM_MCA 17
118#define CARDTYPE_PR_ISA 18
119#define CARDTYPE_PR_MCA 19
120/* Diva Server cards (formerly called Maestra, later Amadeo) */
121#define CARDTYPE_MAESTRA_ISA 20
122#define CARDTYPE_MAESTRA_PCI 21
123/* Diva Server cards to be developed (Quadro, Primary rate) */
124#define CARDTYPE_DIVASRV_Q_8M_PCI 22
125#define CARDTYPE_DIVASRV_P_30M_PCI 23
126#define CARDTYPE_DIVASRV_P_2M_PCI 24
127#define CARDTYPE_DIVASRV_P_9M_PCI 25
128/* DIVA 2.0 cards */
129#define CARDTYPE_DIVA20_ISA 26
130#define CARDTYPE_DIVA20U_ISA 27
131#define CARDTYPE_DIVA20U_PCI 28
132#define CARDTYPE_DIVAPRO20_ISA 29
133#define CARDTYPE_DIVAPRO20U_ISA 30
134#define CARDTYPE_DIVAPRO20U_PCI 31
135/* DIVA combi cards (piccola ISDN + rockwell V.34 modem) */
136#define CARDTYPE_DIVAMOBILE_PCM 32
137#define CARDTYPE_TDKGLOBALPRO_PCM 33
138/* DIVA Pro PC OEM card for 'New Media Corporation' */
139#define CARDTYPE_NMC_DIVAPRO_PCM 34
140/* DIVA Pro 2.0 OEM cards for 'British Telecom' */
141#define CARDTYPE_BT_EXLANE_PCI 35
142#define CARDTYPE_BT_EXLANE_ISA 36
143/* DIVA low cost cards, 1st name DIVA 3.0, 2nd DIVA 2.01, 3rd ??? */
144#define CARDTYPE_DIVALOW_ISA 37
145#define CARDTYPE_DIVALOWU_ISA 38
146#define CARDTYPE_DIVALOW_PCI 39
147#define CARDTYPE_DIVALOWU_PCI 40
148/* DIVA combi cards (piccola ISDN + rockwell V.90 modem) */
149#define CARDTYPE_DIVAMOBILE_V90_PCM 41
150#define CARDTYPE_TDKGLOBPRO_V90_PCM 42
151#define CARDTYPE_DIVASRV_P_23M_PCI 43
152#define CARDTYPE_DIVALOW_USB 44
153/* DIVA Audio (CT) family */
154#define CARDTYPE_DIVA_CT_ST 45
155#define CARDTYPE_DIVA_CT_U 46
156#define CARDTYPE_DIVA_CTLITE_ST 47
157#define CARDTYPE_DIVA_CTLITE_U 48
158/* DIVA ISDN plus V.90 series */
159#define CARDTYPE_DIVAISDN_V90_PCM 49
160#define CARDTYPE_DIVAISDN_V90_PCI 50
161#define CARDTYPE_DIVAISDN_TA 51
162/* DIVA Server Voice cards */
163#define CARDTYPE_DIVASRV_VOICE_Q_8M_PCI 52
164/* DIVA Server V2 cards */
165#define CARDTYPE_DIVASRV_Q_8M_V2_PCI 53
166#define CARDTYPE_DIVASRV_P_30M_V2_PCI 54
167/* DIVA Server Voice V2 cards */
168#define CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI 55
169#define CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI 56
170/* Diva LAN */
171#define CARDTYPE_DIVAISDN_LAN 57
172#define CARDTYPE_DIVA_202_PCI_ST 58
173#define CARDTYPE_DIVA_202_PCI_U 59
174#define CARDTYPE_DIVASRV_B_2M_V2_PCI 60
175#define CARDTYPE_DIVASRV_B_2F_PCI 61
176#define CARDTYPE_DIVALOW_USBV2 62
177#define CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI 63
178#define CARDTYPE_DIVA_PRO_30_PCI_ST 64
179#define CARDTYPE_DIVA_CT_ST_V20 65
180/* Diva Mobile V.90 PC Card and Diva ISDN PC Card */
181#define CARDTYPE_DIVAMOBILE_V2_PCM 66
182#define CARDTYPE_DIVA_V2_PCM 67
183/* Re-badged Diva Pro PC Card */
184#define CARDTYPE_DIVA_PC_CARD 68
185/* next free card type identifier */
186#define CARDTYPE_MAX 69
187/*
188 * The card families
189 */
190#define FAMILY_DIVA 1
191#define FAMILY_S 2
192#define FAMILY_MAESTRA 3
193#define FAMILY_MAX 4
194/*
195 * The basic card types
196 */
197#define CARD_DIVA 1 /* DSP based, old DSP */
198#define CARD_PRO 2 /* DSP based, new DSP */
199#define CARD_PICO 3 /* HSCX based */
200#define CARD_S 4 /* IDI on board based */
201#define CARD_SX 5 /* IDI on board based */
202#define CARD_SXN 6 /* IDI on board based */
203#define CARD_SCOM 7 /* IDI on board based */
204#define CARD_QUAD 8 /* IDI on board based */
205#define CARD_PR 9 /* IDI on board based */
206#define CARD_MAE 10 /* IDI on board based */
207#define CARD_MAEQ 11 /* IDI on board based */
208#define CARD_MAEP 12 /* IDI on board based */
209#define CARD_DIVALOW 13 /* IPAC based */
210#define CARD_CT 14 /* SCOUT based */
211#define CARD_DIVATA 15 /* DIVA TA */
212#define CARD_DIVALAN 16 /* DIVA LAN */
213#define CARD_MAE2 17 /* IDI on board based */
214#define CARD_MAX 18
215/*
216 * The internal card types of the S family
217 */
218#define CARD_I_NONE 0
219#define CARD_I_S 0
220#define CARD_I_SX 1
221#define CARD_I_SCOM 2
222#define CARD_I_QUAD 3
223#define CARD_I_PR 4
224/*
225 * The bus types we support
226 */
227#define BUS_ISA 1
228#define BUS_PCM 2
229#define BUS_PCI 3
230#define BUS_MCA 4
231#define BUS_USB 5
232#define BUS_COM 6
233#define BUS_LAN 7
234/*
235 * The chips we use for B-channel traffic
236 */
237#define CHIP_NONE 0
238#define CHIP_DSP 1
239#define CHIP_HSCX 2
240#define CHIP_IPAC 3
241#define CHIP_SCOUT 4
242#define CHIP_EXTERN 5
243#define CHIP_IPACX 6
244/*
245 * The structures where the card properties are aggregated by id
246 */
247typedef struct CARD_PROPERTIES
248{ char *Name; /* official marketing name */
249 unsigned short PnPId; /* plug and play ID (for non PCMIA cards) */
250 unsigned short Version; /* major and minor version no of the card */
251 unsigned char DescType; /* card type to set in the IDI descriptor */
252 unsigned char Family; /* basic family of the card */
253 unsigned short Features; /* features bits to set in the IDI desc. */
254 unsigned char Card; /* basic card type */
255 unsigned char IType; /* internal type of S cards (read from ram) */
256 unsigned char Bus; /* bus type this card is designed for */
257 unsigned char Chip; /* chipset used on card */
258 unsigned char Adapters; /* number of adapters on card */
259 unsigned char Channels; /* # of channels per adapter */
260 unsigned short E_info; /* # of ram entity info structs per adapter */
261 unsigned short SizeIo; /* size of IO window per adapter */
262 unsigned short SizeMem; /* size of memory window per adapter */
263} CARD_PROPERTIES;
264typedef struct CARD_RESOURCE
265{ unsigned char Int[10];
266 unsigned short IoFirst;
267 unsigned short IoStep;
268 unsigned short IoCnt;
269 unsigned long MemFirst;
270 unsigned long MemStep;
271 unsigned short MemCnt;
272} CARD_RESOURCE;
273/* test if the card of type 't' is a plug & play card */
274#define IS_PNP(t) \
275 ( \
276 ( \
277 CardProperties[t].Bus != BUS_ISA \
278 && \
279 CardProperties[t].Bus != BUS_MCA \
280 ) \
281 || \
282 ( \
283 CardProperties[t].Family != FAMILY_S \
284 && \
285 CardProperties[t].Card != CARD_DIVA \
286 ) \
287 )
288/* extract IDI Descriptor info for card type 't' (p == DescType/Features) */
289#define IDI_PROP(t, p) (CardProperties[t].p)
290#if CARDTYPE_H_WANT_DATA
291#if CARDTYPE_H_WANT_IDI_DATA
292/* include "di_defs.h" for IDI adapter type and feature flag definitions */
293#include "di_defs.h"
294#else /*!CARDTYPE_H_WANT_IDI_DATA*/
295/* define IDI adapter types and feature flags here to prevent inclusion */
296#ifndef IDI_ADAPTER_S
297#define IDI_ADAPTER_S 1
298#define IDI_ADAPTER_PR 2
299#define IDI_ADAPTER_DIVA 3
300#define IDI_ADAPTER_MAESTRA 4
301#endif
302#ifndef DI_VOICE
303#define DI_VOICE 0x0 /* obsolete define */
304#define DI_FAX3 0x1
305#define DI_MODEM 0x2
306#define DI_POST 0x4
307#define DI_V110 0x8
308#define DI_V120 0x10
309#define DI_POTS 0x20
310#define DI_CODEC 0x40
311#define DI_MANAGE 0x80
312#define DI_V_42 0x0100
313#define DI_EXTD_FAX 0x0200 /* Extended FAX (ECM, 2D, T.6, Polling) */
314#define DI_AT_PARSER 0x0400 /* Build-in AT Parser in the L2 */
315#define DI_VOICE_OVER_IP 0x0800 /* Voice over IP support */
316#endif
317#endif /*CARDTYPE_H_WANT_IDI_DATA*/
318#define DI_V1x0 (DI_V110 | DI_V120)
319#define DI_NULL 0x0000
320#if defined(SOFT_DSP_SUPPORT)
321#define SOFT_DSP_ADD_FEATURES (DI_MODEM | DI_FAX3 | DI_AT_PARSER)
322#else
323#define SOFT_DSP_ADD_FEATURES 0
324#endif
325#if defined(SOFT_V110_SUPPORT)
326#define DI_SOFT_V110 DI_V110
327#else
328#define DI_SOFT_V110 0
329#endif
330/*--- CardProperties [Index=CARDTYPE_....] ---------------------------------*/
331CARD_PROPERTIES CardProperties[] =
332{
333 { /* 0 */
334 "Diva MCA", 0x6336, 0x0100,
335 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
336 CARD_DIVA, CARD_I_NONE, BUS_MCA, CHIP_DSP,
337 1, 2, 0, 8, 0
338 },
339 { /* 1 */
340 "Diva ISA", 0x0000, 0x0100,
341 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
342 CARD_DIVA, CARD_I_NONE, BUS_ISA, CHIP_DSP,
343 1, 2, 0, 8, 0
344 },
345 { /* 2 */
346 "Diva/PCM", 0x0000, 0x0100,
347 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
348 CARD_DIVA, CARD_I_NONE, BUS_PCM, CHIP_DSP,
349 1, 2, 0, 8, 0
350 },
351 { /* 3 */
352 "Diva PRO ISA", 0x0031, 0x0100,
353 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
354 CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP,
355 1, 2, 0, 8, 0
356 },
357 { /* 4 */
358 "Diva PRO PC-Card", 0x0000, 0x0100,
359 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
360 CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP,
361 1, 2, 0, 8, 0
362 },
363 { /* 5 */
364 "Diva PICCOLA ISA", 0x0051, 0x0100,
365 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
366 CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX,
367 1, 2, 0, 8, 0
368 },
369 { /* 6 */
370 "Diva PICCOLA PCM", 0x0000, 0x0100,
371 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
372 CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX,
373 1, 2, 0, 8, 0
374 },
375 { /* 7 */
376 "Diva PRO 2.0 S/T PCI", 0xe001, 0x0200,
377 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
378 CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP,
379 1, 2, 0, 8, 0
380 },
381 { /* 8 */
382 "Diva 2.0 S/T PCI", 0xe002, 0x0200,
383 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
384 CARD_PICO, CARD_I_NONE, BUS_PCI, CHIP_HSCX,
385 1, 2, 0, 8, 0
386 },
387 { /* 9 */
388 "QUADRO ISA", 0x0000, 0x0100,
389 IDI_ADAPTER_S, FAMILY_S, DI_NULL,
390 CARD_QUAD, CARD_I_QUAD, BUS_ISA, CHIP_NONE,
391 4, 2, 16, 0, 0x800
392 },
393 { /* 10 */
394 "S ISA", 0x0000, 0x0100,
395 IDI_ADAPTER_S, FAMILY_S, DI_CODEC,
396 CARD_S, CARD_I_S, BUS_ISA, CHIP_NONE,
397 1, 1, 16, 0, 0x800
398 },
399 { /* 11 */
400 "S MCA", 0x6a93, 0x0100,
401 IDI_ADAPTER_S, FAMILY_S, DI_CODEC,
402 CARD_S, CARD_I_S, BUS_MCA, CHIP_NONE,
403 1, 1, 16, 16, 0x400
404 },
405 { /* 12 */
406 "SX ISA", 0x0000, 0x0100,
407 IDI_ADAPTER_S, FAMILY_S, DI_NULL,
408 CARD_SX, CARD_I_SX, BUS_ISA, CHIP_NONE,
409 1, 2, 16, 0, 0x800
410 },
411 { /* 13 */
412 "SX MCA", 0x6a93, 0x0100,
413 IDI_ADAPTER_S, FAMILY_S, DI_NULL,
414 CARD_SX, CARD_I_SX, BUS_MCA, CHIP_NONE,
415 1, 2, 16, 16, 0x400
416 },
417 { /* 14 */
418 "SXN ISA", 0x0000, 0x0100,
419 IDI_ADAPTER_S, FAMILY_S, DI_NULL,
420 CARD_SXN, CARD_I_SCOM, BUS_ISA, CHIP_NONE,
421 1, 2, 16, 0, 0x800
422 },
423 { /* 15 */
424 "SXN MCA", 0x6a93, 0x0100,
425 IDI_ADAPTER_S, FAMILY_S, DI_NULL,
426 CARD_SXN, CARD_I_SCOM, BUS_MCA, CHIP_NONE,
427 1, 2, 16, 16, 0x400
428 },
429 { /* 16 */
430 "SCOM ISA", 0x0000, 0x0100,
431 IDI_ADAPTER_S, FAMILY_S, DI_CODEC,
432 CARD_SCOM, CARD_I_SCOM, BUS_ISA, CHIP_NONE,
433 1, 2, 16, 0, 0x800
434 },
435 { /* 17 */
436 "SCOM MCA", 0x6a93, 0x0100,
437 IDI_ADAPTER_S, FAMILY_S, DI_CODEC,
438 CARD_SCOM, CARD_I_SCOM, BUS_MCA, CHIP_NONE,
439 1, 2, 16, 16, 0x400
440 },
441 { /* 18 */
442 "S2M ISA", 0x0000, 0x0100,
443 IDI_ADAPTER_PR, FAMILY_S, DI_NULL,
444 CARD_PR, CARD_I_PR, BUS_ISA, CHIP_NONE,
445 1, 30, 256, 0, 0x4000
446 },
447 { /* 19 */
448 "S2M MCA", 0x6abb, 0x0100,
449 IDI_ADAPTER_PR, FAMILY_S, DI_NULL,
450 CARD_PR, CARD_I_PR, BUS_MCA, CHIP_NONE,
451 1, 30, 256, 16, 0x4000
452 },
453 { /* 20 */
454 "Diva Server BRI-2M ISA", 0x0041, 0x0100,
455 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
456 CARD_MAE, CARD_I_NONE, BUS_ISA, CHIP_DSP,
457 1, 2, 16, 8, 0
458 },
459 { /* 21 */
460 "Diva Server BRI-2M PCI", 0xE010, 0x0100,
461 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
462 CARD_MAE, CARD_I_NONE, BUS_PCI, CHIP_DSP,
463 1, 2, 16, 8, 0
464 },
465 { /* 22 */
466 "Diva Server 4BRI-8M PCI", 0xE012, 0x0100,
467 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
468 CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP,
469 4, 2, 16, 8, 0
470 },
471 { /* 23 */
472 "Diva Server PRI-30M PCI", 0xE014, 0x0100,
473 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
474 CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP,
475 1, 30, 256, 8, 0
476 },
477 { /* 24 */
478 "Diva Server PRI-2M PCI", 0xe014, 0x0100,
479 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
480 CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP,
481 1, 30, 256, 8, 0
482 },
483 { /* 25 */
484 "Diva Server PRI-9M PCI", 0x0000, 0x0100,
485 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
486 CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP,
487 1, 30, 256, 8, 0
488 },
489 { /* 26 */
490 "Diva 2.0 S/T ISA", 0x0071, 0x0200,
491 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
492 CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX,
493 1, 2, 0, 8, 0
494 },
495 { /* 27 */
496 "Diva 2.0 U ISA", 0x0091, 0x0200,
497 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
498 CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX,
499 1, 2, 0, 8, 0
500 },
501 { /* 28 */
502 "Diva 2.0 U PCI", 0xe004, 0x0200,
503 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
504 CARD_PICO, CARD_I_NONE, BUS_PCI, CHIP_HSCX,
505 1, 2, 0, 8, 0
506 },
507 { /* 29 */
508 "Diva PRO 2.0 S/T ISA", 0x0061, 0x0200,
509 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
510 CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP,
511 1, 2, 0, 8, 0
512 },
513 { /* 30 */
514 "Diva PRO 2.0 U ISA", 0x0081, 0x0200,
515 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
516 CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP,
517 1, 2, 0, 8, 0
518 },
519 { /* 31 */
520 "Diva PRO 2.0 U PCI", 0xe003, 0x0200,
521 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
522 CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP,
523 1, 2, 0, 8, 0
524 },
525 { /* 32 */
526 "Diva MOBILE", 0x0000, 0x0100,
527 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
528 CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX,
529 1, 2, 0, 8, 0
530 },
531 { /* 33 */
532 "TDK DFI3600", 0x0000, 0x0100,
533 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
534 CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX,
535 1, 2, 0, 8, 0
536 },
537 { /* 34 (OEM version of 4 - "Diva PRO PC-Card") */
538 "New Media ISDN", 0x0000, 0x0100,
539 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
540 CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP,
541 1, 2, 0, 8, 0
542 },
543 { /* 35 (OEM version of 7 - "Diva PRO 2.0 S/T PCI") */
544 "BT ExLane PCI", 0xe101, 0x0200,
545 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
546 CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP,
547 1, 2, 0, 8, 0
548 },
549 { /* 36 (OEM version of 29 - "Diva PRO 2.0 S/T ISA") */
550 "BT ExLane ISA", 0x1061, 0x0200,
551 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
552 CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP,
553 1, 2, 0, 8, 0
554 },
555 { /* 37 */
556 "Diva 2.01 S/T ISA", 0x00A1, 0x0300,
557 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
558 CARD_DIVALOW, CARD_I_NONE, BUS_ISA, CHIP_IPAC,
559 1, 2, 0, 8, 0
560 },
561 { /* 38 */
562 "Diva 2.01 U ISA", 0x00B1, 0x0300,
563 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
564 CARD_DIVALOW, CARD_I_NONE, BUS_ISA, CHIP_IPAC,
565 1, 2, 0, 8, 0
566 },
567 { /* 39 */
568 "Diva 2.01 S/T PCI", 0xe005, 0x0300,
569 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
570 CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC,
571 1, 2, 0, 8, 0
572 },
573 { /* 40 no ID yet */
574 "Diva 2.01 U PCI", 0x0000, 0x0300,
575 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
576 CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC,
577 1, 2, 0, 8, 0
578 },
579 { /* 41 */
580 "Diva MOBILE V.90", 0x0000, 0x0100,
581 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
582 CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX,
583 1, 2, 0, 8, 0
584 },
585 { /* 42 */
586 "TDK DFI3600 V.90", 0x0000, 0x0100,
587 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
588 CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX,
589 1, 2, 0, 8, 0
590 },
591 { /* 43 */
592 "Diva Server PRI-23M PCI", 0xe014, 0x0100,
593 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
594 CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP,
595 1, 30, 256, 8, 0
596 },
597 { /* 44 */
598 "Diva 2.01 S/T USB", 0x1000, 0x0300,
599 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
600 CARD_DIVALOW, CARD_I_NONE, BUS_USB, CHIP_IPAC,
601 1, 2, 0, 8, 0
602 },
603 { /* 45 */
604 "Diva CT S/T PCI", 0xe006, 0x0300,
605 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
606 CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP,
607 1, 2, 0, 0, 0
608 },
609 { /* 46 */
610 "Diva CT U PCI", 0xe007, 0x0300,
611 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
612 CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP,
613 1, 2, 0, 0, 0
614 },
615 { /* 47 */
616 "Diva CT Lite S/T PCI", 0xe008, 0x0300,
617 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
618 CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP,
619 1, 2, 0, 0, 0
620 },
621 { /* 48 */
622 "Diva CT Lite U PCI", 0xe009, 0x0300,
623 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
624 CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP,
625 1, 2, 0, 0, 0
626 },
627 { /* 49 */
628 "Diva ISDN+V.90 PC Card", 0x8D8C, 0x0100,
629 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
630 CARD_DIVALOW, CARD_I_NONE, BUS_PCM, CHIP_IPAC,
631 1, 2, 0, 8, 0
632 },
633 { /* 50 */
634 "Diva ISDN+V.90 PCI", 0xe00A, 0x0100,
635 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
636 CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC,
637 1, 2, 0, 8, 0
638 },
639 { /* 51 (DivaTA) no ID */
640 "Diva TA", 0x0000, 0x0300,
641 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES,
642 CARD_DIVATA, CARD_I_NONE, BUS_COM, CHIP_EXTERN,
643 1, 1, 0, 8, 0
644 },
645 { /* 52 (Diva Server 4BRI-8M PCI adapter enabled for Voice) */
646 "Diva Server Voice 4BRI-8M PCI", 0xE016, 0x0100,
647 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
648 CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP,
649 4, 2, 16, 8, 0
650 },
651 { /* 53 (Diva Server 4BRI 2.0 adapter) */
652 "Diva Server 4BRI-8M 2.0 PCI", 0xE013, 0x0200,
653 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
654 CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP,
655 4, 2, 16, 8, 0
656 },
657 { /* 54 (Diva Server PRI 2.0 adapter) */
658 "Diva Server PRI 2.0 PCI", 0xE015, 0x0200,
659 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
660 CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP,
661 1, 30, 256, 8, 0
662 },
663 { /* 55 (Diva Server 4BRI-8M 2.0 PCI adapter enabled for Voice) */
664 "Diva Server Voice 4BRI-8M 2.0 PCI", 0xE017, 0x0200,
665 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
666 CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP,
667 4, 2, 16, 8, 0
668 },
669 { /* 56 (Diva Server PRI 2.0 PCI adapter enabled for Voice) */
670 "Diva Server Voice PRI 2.0 PCI", 0xE019, 0x0200,
671 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
672 CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP,
673 1, 30, 256, 8, 0
674 },
675 {
676 /* 57 (DivaLan ) no ID */
677 "Diva LAN", 0x0000, 0x0300,
678 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES,
679 CARD_DIVALAN, CARD_I_NONE, BUS_LAN, CHIP_EXTERN,
680 1, 1, 0, 8, 0
681 },
682 { /* 58 */
683 "Diva 2.02 PCI S/T", 0xE00B, 0x0300,
684 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES | DI_SOFT_V110,
685 CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPACX,
686 1, 2, 0, 8, 0
687 },
688 { /* 59 */
689 "Diva 2.02 PCI U", 0xE00C, 0x0300,
690 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
691 CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPACX,
692 1, 2, 0, 8, 0
693 },
694 { /* 60 */
695 "Diva Server BRI-2M 2.0 PCI", 0xE018, 0x0200,
696 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
697 CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_DSP,
698 1, 2, 16, 8, 0
699 },
700 { /* 61 (the previous name was Diva Server BRI-2F 2.0 PCI) */
701 "Diva Server 2FX", 0xE01A, 0x0200,
702 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_SOFT_V110,
703 CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_IPACX,
704 1, 2, 16, 8, 0
705 },
706 { /* 62 */
707 " Diva ISDN USB 2.0", 0x1003, 0x0300,
708 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
709 CARD_DIVALOW, CARD_I_NONE, BUS_USB, CHIP_IPACX,
710 1, 2, 0, 8, 0
711 },
712 { /* 63 (Diva Server BRI-2M 2.0 PCI adapter enabled for Voice) */
713 "Diva Server Voice BRI-2M 2.0 PCI", 0xE01B, 0x0200,
714 IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
715 CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_DSP,
716 1, 2, 16, 8, 0
717 },
718 { /* 64 */
719 "Diva Pro 3.0 PCI", 0xe00d, 0x0300,
720 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
721 CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP,
722 1, 2, 0, 0, 0
723 },
724 { /* 65 */
725 "Diva ISDN + CT 2.0", 0xE00E, 0x0300,
726 IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
727 CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP,
728 1, 2, 0, 0, 0
729 },
730 { /* 66 */
731 "Diva Mobile V.90 PC Card", 0x8331, 0x0100,
732 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
733 CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_IPACX,
734 1, 2, 0, 8, 0
735 },
736 { /* 67 */
737 "Diva ISDN PC Card", 0x8311, 0x0100,
738 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
739 CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_IPACX,
740 1, 2, 0, 8, 0
741 },
742 { /* 68 */
743 "Diva ISDN PC Card", 0x0000, 0x0100,
744 IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
745 CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP,
746 1, 2, 0, 8, 0
747 },
748};
749#if CARDTYPE_H_WANT_RESOURCE_DATA
750/*--- CardResource [Index=CARDTYPE_....] ---------------------------(GEI)-*/
751CARD_RESOURCE CardResource[] = {
752/* Interrupts IO-Address Mem-Address */
753 /* 0*/ { 3,4,9,0,0,0,0,0,0,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA MCA
754 /* 1*/ { 3,4,9,10,11,12,0,0,0,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA ISA
755 /* 2*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PCMCIA
756 /* 3*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO ISA
757 /* 4*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO PCMCIA
758 /* 5*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PICCOLA ISA
759 /* 6*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA PICCOLA PCMCIA
760 /* 7*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO 2.0 PCI
761 /* 8*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.0 PCI
762 /* 9*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x2000,64 }, // QUADRO ISA
763 /*10*/ { 3,4,9,10,11,12,0,0,0,0, 0x0,0x0,0, 0xc0000,0x2000,16 }, // S ISA
764 /*11*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // S MCA
765 /*12*/ { 3,4,9,10,11,12,0,0,0,0, 0x0,0x0,0, 0xc0000,0x2000,16 }, // SX ISA
766 /*13*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SX MCA
767 /*14*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x0800,256 }, // SXN ISA
768 /*15*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SXN MCA
769 /*16*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x0800,256 }, // SCOM ISA
770 /*17*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SCOM MCA
771 /*18*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0xc0000,0x4000,16 }, // S2M ISA
772 /*19*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x4000,16 }, // S2M MCA
773 /*20*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA ISA
774 /*21*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA PCI
775 /*22*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA QUADRO ISA
776 /*23*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA QUADRO PCI
777 /*24*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA PRIMARY ISA
778 /*25*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA PRIMARY PCI
779 /*26*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.0 ISA
780 /*27*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.0 /U ISA
781 /*28*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.0 /U PCI
782 /*29*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO 2.0 ISA
783 /*30*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO 2.0 /U ISA
784 /*31*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO 2.0 /U PCI
785 /*32*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA MOBILE
786 /*33*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // TDK DFI3600 (same as DIVA MOBILE [32])
787 /*34*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // New Media ISDN (same as DIVA PRO PCMCIA [4])
788 /*35*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // BT ExLane PCI (same as DIVA PRO 2.0 PCI [7])
789 /*36*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // BT ExLane ISA (same as DIVA PRO 2.0 ISA [29])
790 /*37*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.01 S/T ISA
791 /*38*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.01 U ISA
792 /*39*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.01 S/T PCI
793 /*40*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.01 U PCI
794 /*41*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA MOBILE V.90
795 /*42*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // TDK DFI3600 V.90 (same as DIVA MOBILE V.90 [39])
796 /*43*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // DIVA Server PRI-23M PCI
797 /*44*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA 2.01 S/T USB
798 /*45*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT S/T PCI
799 /*46*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT U PCI
800 /*47*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT Lite S/T PCI
801 /*48*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT Lite U PCI
802 /*49*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA ISDN+V.90 PC Card
803 /*50*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA ISDN+V.90 PCI
804 /*51*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA TA
805 /*52*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI
806 /*53*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI
807 /*54*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA VOICE PRIMARY PCI
808 /*55*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI
809 /*56*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA VOICE PRIMARY PCI
810 /*57*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA LAN
811 /*58*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.02 S/T PCI
812 /*59*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.02 U PCI
813 /*60*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server BRI-2M 2.0 PCI
814 /*61*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server BRI-2F PCI
815 /*62*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA 2.01 S/T USB
816 /*63*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server Voice BRI-2M 2.0 PCI
817 /*64*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 3.0 PCI
818 /*65*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT S/T PCI V2.0
819 /*66*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA Mobile V.90 PC Card
820 /*67*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA ISDN PC Card
821 /*68*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA ISDN PC Card
822};
823#endif /*CARDTYPE_H_WANT_RESOURCE_DATA*/
824#else /*!CARDTYPE_H_WANT_DATA*/
825extern CARD_PROPERTIES CardProperties[];
826extern CARD_RESOURCE CardResource[];
827#endif /*CARDTYPE_H_WANT_DATA*/
828/*
829 * all existing download files
830 */
831#define CARD_DSP_CNT 5
832#define CARD_PROT_CNT 9
833#define CARD_FT_UNKNOWN 0
834#define CARD_FT_B 1
835#define CARD_FT_D 2
836#define CARD_FT_S 3
837#define CARD_FT_M 4
838#define CARD_FT_NEW_DSP_COMBIFILE 5 /* File format of new DSP code (the DSP code powered by Telindus) */
839#define CARD_FILE_NONE 0
840#define CARD_B_S 1
841#define CARD_B_P 2
842#define CARD_D_K1 3
843#define CARD_D_K2 4
844#define CARD_D_H 5
845#define CARD_D_V 6
846#define CARD_D_M 7
847#define CARD_D_F 8
848#define CARD_P_S_E 9
849#define CARD_P_S_1 10
850#define CARD_P_S_B 11
851#define CARD_P_S_F 12
852#define CARD_P_S_A 13
853#define CARD_P_S_N 14
854#define CARD_P_S_5 15
855#define CARD_P_S_J 16
856#define CARD_P_SX_E 17
857#define CARD_P_SX_1 18
858#define CARD_P_SX_B 19
859#define CARD_P_SX_F 20
860#define CARD_P_SX_A 21
861#define CARD_P_SX_N 22
862#define CARD_P_SX_5 23
863#define CARD_P_SX_J 24
864#define CARD_P_SY_E 25
865#define CARD_P_SY_1 26
866#define CARD_P_SY_B 27
867#define CARD_P_SY_F 28
868#define CARD_P_SY_A 29
869#define CARD_P_SY_N 30
870#define CARD_P_SY_5 31
871#define CARD_P_SY_J 32
872#define CARD_P_SQ_E 33
873#define CARD_P_SQ_1 34
874#define CARD_P_SQ_B 35
875#define CARD_P_SQ_F 36
876#define CARD_P_SQ_A 37
877#define CARD_P_SQ_N 38
878#define CARD_P_SQ_5 39
879#define CARD_P_SQ_J 40
880#define CARD_P_P_E 41
881#define CARD_P_P_1 42
882#define CARD_P_P_B 43
883#define CARD_P_P_F 44
884#define CARD_P_P_A 45
885#define CARD_P_P_N 46
886#define CARD_P_P_5 47
887#define CARD_P_P_J 48
888#define CARD_P_M_E 49
889#define CARD_P_M_1 50
890#define CARD_P_M_B 51
891#define CARD_P_M_F 52
892#define CARD_P_M_A 53
893#define CARD_P_M_N 54
894#define CARD_P_M_5 55
895#define CARD_P_M_J 56
896#define CARD_P_S_S 57
897#define CARD_P_SX_S 58
898#define CARD_P_SY_S 59
899#define CARD_P_SQ_S 60
900#define CARD_P_P_S 61
901#define CARD_P_M_S 62
902#define CARD_D_NEW_DSP_COMBIFILE 63
903typedef struct CARD_FILES_DATA
904{
905 char *Name;
906 unsigned char Type;
907}
908 CARD_FILES_DATA;
909typedef struct CARD_FILES
910{
911 unsigned char Boot;
912 unsigned char Dsp[CARD_DSP_CNT];
913 unsigned char DspTelindus;
914 unsigned char Prot[CARD_PROT_CNT];
915}
916 CARD_FILES;
917#if CARDTYPE_H_WANT_DATA
918#if CARDTYPE_H_WANT_FILE_DATA
919CARD_FILES_DATA CardFData[] = {
920// Filename Filetype
921 0, CARD_FT_UNKNOWN,
922 "didnload.bin", CARD_FT_B,
923 "diprload.bin", CARD_FT_B,
924 "didiva.bin", CARD_FT_D,
925 "didivapp.bin", CARD_FT_D,
926 "dihscx.bin", CARD_FT_D,
927 "div110.bin", CARD_FT_D,
928 "dimodem.bin", CARD_FT_D,
929 "difax.bin", CARD_FT_D,
930 "di_etsi.bin", CARD_FT_S,
931 "di_1tr6.bin", CARD_FT_S,
932 "di_belg.bin", CARD_FT_S,
933 "di_franc.bin", CARD_FT_S,
934 "di_atel.bin", CARD_FT_S,
935 "di_ni.bin", CARD_FT_S,
936 "di_5ess.bin", CARD_FT_S,
937 "di_japan.bin", CARD_FT_S,
938 "di_etsi.sx", CARD_FT_S,
939 "di_1tr6.sx", CARD_FT_S,
940 "di_belg.sx", CARD_FT_S,
941 "di_franc.sx", CARD_FT_S,
942 "di_atel.sx", CARD_FT_S,
943 "di_ni.sx", CARD_FT_S,
944 "di_5ess.sx", CARD_FT_S,
945 "di_japan.sx", CARD_FT_S,
946 "di_etsi.sy", CARD_FT_S,
947 "di_1tr6.sy", CARD_FT_S,
948 "di_belg.sy", CARD_FT_S,
949 "di_franc.sy", CARD_FT_S,
950 "di_atel.sy", CARD_FT_S,
951 "di_ni.sy", CARD_FT_S,
952 "di_5ess.sy", CARD_FT_S,
953 "di_japan.sy", CARD_FT_S,
954 "di_etsi.sq", CARD_FT_S,
955 "di_1tr6.sq", CARD_FT_S,
956 "di_belg.sq", CARD_FT_S,
957 "di_franc.sq", CARD_FT_S,
958 "di_atel.sq", CARD_FT_S,
959 "di_ni.sq", CARD_FT_S,
960 "di_5ess.sq", CARD_FT_S,
961 "di_japan.sq", CARD_FT_S,
962 "di_etsi.p", CARD_FT_S,
963 "di_1tr6.p", CARD_FT_S,
964 "di_belg.p", CARD_FT_S,
965 "di_franc.p", CARD_FT_S,
966 "di_atel.p", CARD_FT_S,
967 "di_ni.p", CARD_FT_S,
968 "di_5ess.p", CARD_FT_S,
969 "di_japan.p", CARD_FT_S,
970 "di_etsi.sm", CARD_FT_M,
971 "di_1tr6.sm", CARD_FT_M,
972 "di_belg.sm", CARD_FT_M,
973 "di_franc.sm", CARD_FT_M,
974 "di_atel.sm", CARD_FT_M,
975 "di_ni.sm", CARD_FT_M,
976 "di_5ess.sm", CARD_FT_M,
977 "di_japan.sm", CARD_FT_M,
978 "di_swed.bin", CARD_FT_S,
979 "di_swed.sx", CARD_FT_S,
980 "di_swed.sy", CARD_FT_S,
981 "di_swed.sq", CARD_FT_S,
982 "di_swed.p", CARD_FT_S,
983 "di_swed.sm", CARD_FT_M,
984 "didspdld.bin", CARD_FT_NEW_DSP_COMBIFILE
985};
986CARD_FILES CardFiles[] =
987{
988 { /* CARD_UNKNOWN */
989 CARD_FILE_NONE,
990 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
991 CARD_FILE_NONE,
992 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
993 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
994 CARD_FILE_NONE
995 },
996 { /* CARD_DIVA */
997 CARD_FILE_NONE,
998 CARD_D_K1, CARD_D_H, CARD_D_V, CARD_FILE_NONE, CARD_D_F,
999 CARD_D_NEW_DSP_COMBIFILE,
1000 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1001 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1002 CARD_FILE_NONE
1003 },
1004 { /* CARD_PRO */
1005 CARD_FILE_NONE,
1006 CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F,
1007 CARD_D_NEW_DSP_COMBIFILE,
1008 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1009 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1010 CARD_FILE_NONE
1011 },
1012 { /* CARD_PICO */
1013 CARD_FILE_NONE,
1014 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1015 CARD_FILE_NONE,
1016 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1017 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1018 CARD_FILE_NONE
1019 },
1020 { /* CARD_S */
1021 CARD_B_S,
1022 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1023 CARD_FILE_NONE,
1024 CARD_P_S_E, CARD_P_S_1, CARD_P_S_B, CARD_P_S_F,
1025 CARD_P_S_A, CARD_P_S_N, CARD_P_S_5, CARD_P_S_J,
1026 CARD_P_S_S
1027 },
1028 { /* CARD_SX */
1029 CARD_B_S,
1030 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1031 CARD_FILE_NONE,
1032 CARD_P_SX_E, CARD_P_SX_1, CARD_P_SX_B, CARD_P_SX_F,
1033 CARD_P_SX_A, CARD_P_SX_N, CARD_P_SX_5, CARD_P_SX_J,
1034 CARD_P_SX_S
1035 },
1036 { /* CARD_SXN */
1037 CARD_B_S,
1038 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1039 CARD_FILE_NONE,
1040 CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F,
1041 CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J,
1042 CARD_P_SY_S
1043 },
1044 { /* CARD_SCOM */
1045 CARD_B_S,
1046 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1047 CARD_FILE_NONE,
1048 CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F,
1049 CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J,
1050 CARD_P_SY_S
1051 },
1052 { /* CARD_QUAD */
1053 CARD_B_S,
1054 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1055 CARD_FILE_NONE,
1056 CARD_P_SQ_E, CARD_P_SQ_1, CARD_P_SQ_B, CARD_P_SQ_F,
1057 CARD_P_SQ_A, CARD_P_SQ_N, CARD_P_SQ_5, CARD_P_SQ_J,
1058 CARD_P_SQ_S
1059 },
1060 { /* CARD_PR */
1061 CARD_B_P,
1062 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1063 CARD_FILE_NONE,
1064 CARD_P_P_E, CARD_P_P_1, CARD_P_P_B, CARD_P_P_F,
1065 CARD_P_P_A, CARD_P_P_N, CARD_P_P_5, CARD_P_P_J,
1066 CARD_P_P_S
1067 },
1068 { /* CARD_MAE */
1069 CARD_FILE_NONE,
1070 CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F,
1071 CARD_D_NEW_DSP_COMBIFILE,
1072 CARD_P_M_E, CARD_P_M_1, CARD_P_M_B, CARD_P_M_F,
1073 CARD_P_M_A, CARD_P_M_N, CARD_P_M_5, CARD_P_M_J,
1074 CARD_P_M_S
1075 },
1076 { /* CARD_MAEQ */ /* currently not supported */
1077 CARD_FILE_NONE,
1078 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1079 CARD_FILE_NONE,
1080 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1081 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1082 CARD_FILE_NONE
1083 },
1084 { /* CARD_MAEP */ /* currently not supported */
1085 CARD_FILE_NONE,
1086 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1087 CARD_FILE_NONE,
1088 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1089 CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
1090 CARD_FILE_NONE
1091 }
1092};
1093#endif /*CARDTYPE_H_WANT_FILE_DATA*/
1094#else /*!CARDTYPE_H_WANT_DATA*/
1095extern CARD_FILES_DATA CardFData[];
1096extern CARD_FILES CardFiles[];
1097#endif /*CARDTYPE_H_WANT_DATA*/
1098#endif /* _CARDTYPE_H_ */
diff --git a/drivers/isdn/hardware/eicon/cp_vers.h b/drivers/isdn/hardware/eicon/cp_vers.h
deleted file mode 100644
index c97230c60e71..000000000000
--- a/drivers/isdn/hardware/eicon/cp_vers.h
+++ /dev/null
@@ -1,26 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26static char diva_capi_common_code_build[] = "102-28";
diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c
deleted file mode 100644
index 51420999418d..000000000000
--- a/drivers/isdn/hardware/eicon/dadapter.c
+++ /dev/null
@@ -1,364 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Networks, 2002.
4 *
5 This source file is supplied for the use with
6 Eicon Networks range of DIVA Server Adapters.
7 *
8 Eicon File Revision : 2.1
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, or (at your option)
13 any later version.
14 *
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the 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 */
25#include "platform.h"
26#include "pc.h"
27#include "debuglib.h"
28#include "di_defs.h"
29#include "divasync.h"
30#include "dadapter.h"
31/* --------------------------------------------------------------------------
32 Adapter array change notification framework
33 -------------------------------------------------------------------------- */
34typedef struct _didd_adapter_change_notification {
35 didd_adapter_change_callback_t callback;
36 void IDI_CALL_ENTITY_T *context;
37} didd_adapter_change_notification_t, \
38 * IDI_CALL_ENTITY_T pdidd_adapter_change_notification_t;
39#define DIVA_DIDD_MAX_NOTIFICATIONS 256
40static didd_adapter_change_notification_t \
41NotificationTable[DIVA_DIDD_MAX_NOTIFICATIONS];
42/* --------------------------------------------------------------------------
43 Array to held adapter information
44 -------------------------------------------------------------------------- */
45static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS];
46static dword Adapters = 0; /* Number of adapters */
47/* --------------------------------------------------------------------------
48 Shadow IDI_DIMAINT
49 and 'shadow' debug stuff
50 -------------------------------------------------------------------------- */
51static void no_printf(unsigned char *format, ...)
52{
53#ifdef EBUG
54 va_list ap;
55 va_start(ap, format);
56 debug((format, ap));
57 va_end(ap);
58#endif
59}
60
61/* -------------------------------------------------------------------------
62 Portable debug Library
63 ------------------------------------------------------------------------- */
64#include "debuglib.c"
65
66static DESCRIPTOR MAdapter = {IDI_DIMAINT, /* Adapter Type */
67 0x00, /* Channels */
68 0x0000, /* Features */
69 (IDI_CALL)no_printf};
70/* --------------------------------------------------------------------------
71 DAdapter. Only IDI clients with buffer, that is huge enough to
72 get all descriptors will receive information about DAdapter
73 { byte type, byte channels, word features, IDI_CALL request }
74 -------------------------------------------------------------------------- */
75static void IDI_CALL_LINK_T diva_dadapter_request(ENTITY IDI_CALL_ENTITY_T *);
76static DESCRIPTOR DAdapter = {IDI_DADAPTER, /* Adapter Type */
77 0x00, /* Channels */
78 0x0000, /* Features */
79 diva_dadapter_request };
80/* --------------------------------------------------------------------------
81 LOCALS
82 -------------------------------------------------------------------------- */
83static dword diva_register_adapter_callback(\
84 didd_adapter_change_callback_t callback,
85 void IDI_CALL_ENTITY_T *context);
86static void diva_remove_adapter_callback(dword handle);
87static void diva_notify_adapter_change(DESCRIPTOR *d, int removal);
88static diva_os_spin_lock_t didd_spin;
89/* --------------------------------------------------------------------------
90 Should be called as first step, after driver init
91 -------------------------------------------------------------------------- */
92void diva_didd_load_time_init(void) {
93 memset(&HandleTable[0], 0x00, sizeof(HandleTable));
94 memset(&NotificationTable[0], 0x00, sizeof(NotificationTable));
95 diva_os_initialize_spin_lock(&didd_spin, "didd");
96}
97/* --------------------------------------------------------------------------
98 Should be called as last step, if driver does unload
99 -------------------------------------------------------------------------- */
100void diva_didd_load_time_finit(void) {
101 diva_os_destroy_spin_lock(&didd_spin, "didd");
102}
103/* --------------------------------------------------------------------------
104 Called in order to register new adapter in adapter array
105 return adapter handle (> 0) on success
106 return -1 adapter array overflow
107 -------------------------------------------------------------------------- */
108static int diva_didd_add_descriptor(DESCRIPTOR *d) {
109 diva_os_spin_lock_magic_t irql;
110 int i;
111 if (d->type == IDI_DIMAINT) {
112 if (d->request) {
113 MAdapter.request = d->request;
114 dprintf = (DIVA_DI_PRINTF)d->request;
115 diva_notify_adapter_change(&MAdapter, 0); /* Inserted */
116 DBG_TRC(("DIMAINT registered, dprintf=%08x", d->request))
117 } else {
118 DBG_TRC(("DIMAINT removed"))
119 diva_notify_adapter_change(&MAdapter, 1); /* About to remove */
120 MAdapter.request = (IDI_CALL)no_printf;
121 dprintf = no_printf;
122 }
123 return (NEW_MAX_DESCRIPTORS);
124 }
125 for (i = 0; i < NEW_MAX_DESCRIPTORS; i++) {
126 diva_os_enter_spin_lock(&didd_spin, &irql, "didd_add");
127 if (HandleTable[i].type == 0) {
128 memcpy(&HandleTable[i], d, sizeof(*d));
129 Adapters++;
130 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_add");
131 diva_notify_adapter_change(d, 0); /* we have new adapter */
132 DBG_TRC(("Add adapter[%d], request=%08x", (i + 1), d->request))
133 return (i + 1);
134 }
135 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_add");
136 }
137 DBG_ERR(("Can't add adapter, out of resources"))
138 return (-1);
139}
140/* --------------------------------------------------------------------------
141 Called in order to remove one registered adapter from array
142 return adapter handle (> 0) on success
143 return 0 on success
144 -------------------------------------------------------------------------- */
145static int diva_didd_remove_descriptor(IDI_CALL request) {
146 diva_os_spin_lock_magic_t irql;
147 int i;
148 if (request == MAdapter.request) {
149 DBG_TRC(("DIMAINT removed"))
150 dprintf = no_printf;
151 diva_notify_adapter_change(&MAdapter, 1); /* About to remove */
152 MAdapter.request = (IDI_CALL)no_printf;
153 return (0);
154 }
155 for (i = 0; (Adapters && (i < NEW_MAX_DESCRIPTORS)); i++) {
156 if (HandleTable[i].request == request) {
157 diva_notify_adapter_change(&HandleTable[i], 1); /* About to remove */
158 diva_os_enter_spin_lock(&didd_spin, &irql, "didd_rm");
159 memset(&HandleTable[i], 0x00, sizeof(HandleTable[0]));
160 Adapters--;
161 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_rm");
162 DBG_TRC(("Remove adapter[%d], request=%08x", (i + 1), request))
163 return (0);
164 }
165 }
166 DBG_ERR(("Invalid request=%08x, can't remove adapter", request))
167 return (-1);
168}
169/* --------------------------------------------------------------------------
170 Read adapter array
171 return 1 if not enough space to save all available adapters
172 -------------------------------------------------------------------------- */
173static int diva_didd_read_adapter_array(DESCRIPTOR *buffer, int length) {
174 diva_os_spin_lock_magic_t irql;
175 int src, dst;
176 memset(buffer, 0x00, length);
177 length /= sizeof(DESCRIPTOR);
178 DBG_TRC(("DIDD_Read, space = %d, Adapters = %d", length, Adapters + 2))
179
180 diva_os_enter_spin_lock(&didd_spin, &irql, "didd_read");
181 for (src = 0, dst = 0;
182 (Adapters && (src < NEW_MAX_DESCRIPTORS) && (dst < length));
183 src++) {
184 if (HandleTable[src].type) {
185 memcpy(&buffer[dst], &HandleTable[src], sizeof(DESCRIPTOR));
186 dst++;
187 }
188 }
189 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_read");
190 if (dst < length) {
191 memcpy(&buffer[dst], &MAdapter, sizeof(DESCRIPTOR));
192 dst++;
193 } else {
194 DBG_ERR(("Can't write DIMAINT. Array too small"))
195 }
196 if (dst < length) {
197 memcpy(&buffer[dst], &DAdapter, sizeof(DESCRIPTOR));
198 dst++;
199 } else {
200 DBG_ERR(("Can't write DADAPTER. Array too small"))
201 }
202 DBG_TRC(("Read %d adapters", dst))
203 return (dst == length);
204}
205/* --------------------------------------------------------------------------
206 DAdapter request function.
207 This function does process only synchronous requests, and is used
208 for reception/registration of new interfaces
209 -------------------------------------------------------------------------- */
210static void IDI_CALL_LINK_T diva_dadapter_request( \
211 ENTITY IDI_CALL_ENTITY_T *e) {
212 IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e;
213 if (e->Req) { /* We do not process it, also return error */
214 e->Rc = OUT_OF_RESOURCES;
215 DBG_ERR(("Can't process async request, Req=%02x", e->Req))
216 return;
217 }
218 /*
219 So, we process sync request
220 */
221 switch (e->Rc) {
222 case IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY: {
223 diva_didd_adapter_notify_t *pinfo = &syncReq->didd_notify.info;
224 pinfo->handle = diva_register_adapter_callback( \
225 (didd_adapter_change_callback_t)pinfo->callback,
226 (void IDI_CALL_ENTITY_T *)pinfo->context);
227 e->Rc = 0xff;
228 } break;
229 case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY: {
230 diva_didd_adapter_notify_t *pinfo = &syncReq->didd_notify.info;
231 diva_remove_adapter_callback(pinfo->handle);
232 e->Rc = 0xff;
233 } break;
234 case IDI_SYNC_REQ_DIDD_ADD_ADAPTER: {
235 diva_didd_add_adapter_t *pinfo = &syncReq->didd_add_adapter.info;
236 if (diva_didd_add_descriptor((DESCRIPTOR *)pinfo->descriptor) < 0) {
237 e->Rc = OUT_OF_RESOURCES;
238 } else {
239 e->Rc = 0xff;
240 }
241 } break;
242 case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER: {
243 diva_didd_remove_adapter_t *pinfo = &syncReq->didd_remove_adapter.info;
244 if (diva_didd_remove_descriptor((IDI_CALL)pinfo->p_request) < 0) {
245 e->Rc = OUT_OF_RESOURCES;
246 } else {
247 e->Rc = 0xff;
248 }
249 } break;
250 case IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY: {
251 diva_didd_read_adapter_array_t *pinfo =\
252 &syncReq->didd_read_adapter_array.info;
253 if (diva_didd_read_adapter_array((DESCRIPTOR *)pinfo->buffer,
254 (int)pinfo->length)) {
255 e->Rc = OUT_OF_RESOURCES;
256 } else {
257 e->Rc = 0xff;
258 }
259 } break;
260 default:
261 DBG_ERR(("Can't process sync request, Req=%02x", e->Rc))
262 e->Rc = OUT_OF_RESOURCES;
263 }
264}
265/* --------------------------------------------------------------------------
266 IDI client does register his notification function
267 -------------------------------------------------------------------------- */
268static dword diva_register_adapter_callback( \
269 didd_adapter_change_callback_t callback,
270 void IDI_CALL_ENTITY_T *context) {
271 diva_os_spin_lock_magic_t irql;
272 dword i;
273
274 for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) {
275 diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy_add");
276 if (!NotificationTable[i].callback) {
277 NotificationTable[i].callback = callback;
278 NotificationTable[i].context = context;
279 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_add");
280 DBG_TRC(("Register adapter notification[%d]=%08x", i + 1, callback))
281 return (i + 1);
282 }
283 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_add");
284 }
285 DBG_ERR(("Can't register adapter notification, overflow"))
286 return (0);
287}
288/* --------------------------------------------------------------------------
289 IDI client does register his notification function
290 -------------------------------------------------------------------------- */
291static void diva_remove_adapter_callback(dword handle) {
292 diva_os_spin_lock_magic_t irql;
293 if (handle && ((--handle) < DIVA_DIDD_MAX_NOTIFICATIONS)) {
294 diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy_rm");
295 NotificationTable[handle].callback = NULL;
296 NotificationTable[handle].context = NULL;
297 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_rm");
298 DBG_TRC(("Remove adapter notification[%d]", (int)(handle + 1)))
299 return;
300 }
301 DBG_ERR(("Can't remove adapter notification, handle=%d", handle))
302 }
303/* --------------------------------------------------------------------------
304 Notify all client about adapter array change
305 Does suppose following behavior in the client side:
306 Step 1: Redister Notification
307 Step 2: Read Adapter Array
308 -------------------------------------------------------------------------- */
309static void diva_notify_adapter_change(DESCRIPTOR *d, int removal) {
310 int i, do_notify;
311 didd_adapter_change_notification_t nfy;
312 diva_os_spin_lock_magic_t irql;
313 for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) {
314 do_notify = 0;
315 diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy");
316 if (NotificationTable[i].callback) {
317 memcpy(&nfy, &NotificationTable[i], sizeof(nfy));
318 do_notify = 1;
319 }
320 diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy");
321 if (do_notify) {
322 (*(nfy.callback))(nfy.context, d, removal);
323 }
324 }
325}
326/* --------------------------------------------------------------------------
327 For all systems, that are linked by Kernel Mode Linker this is ONLY one
328 function thet should be exported by this device driver
329 IDI clients should look for IDI_DADAPTER, and use request function
330 of this adapter (sync request) in order to receive appropriate services:
331 - add new adapter
332 - remove existing adapter
333 - add adapter array notification
334 - remove adapter array notification
335 (read adapter is redundant in this case)
336 INPUT:
337 buffer - pointer to buffer that will receive adapter array
338 length - length (in bytes) of space in buffer
339 OUTPUT:
340 Adapter array will be written to memory described by 'buffer'
341 If the last adapter seen in the returned adapter array is
342 IDI_DADAPTER or if last adapter in array does have type '0', then
343 it was enougth space in buffer to accommodate all available
344 adapter descriptors
345 *NOTE 1 (debug interface):
346 The IDI adapter of type 'IDI_DIMAINT' does register as 'request'
347 famous 'dprintf' function (of type DI_PRINTF, please look
348 include/debuglib.c and include/debuglib.h) for details.
349 So dprintf is not exported from module debug module directly,
350 instead of this IDI_DIMAINT is registered.
351 Module load order will receive in this case:
352 1. DIDD (this file)
353 2. DIMAINT does load and register 'IDI_DIMAINT', at this step
354 DIDD should be able to get 'dprintf', save it, and
355 register with DIDD by means of 'dprintf' function.
356 3. any other driver is loaded and is able to access adapter array
357 and debug interface
358 This approach does allow to load/unload debug interface on demand,
359 and save memory, it it is necessary.
360 -------------------------------------------------------------------------- */
361void IDI_CALL_LINK_T DIVA_DIDD_Read(void IDI_CALL_ENTITY_T *buffer,
362 int length) {
363 diva_didd_read_adapter_array(buffer, length);
364}
diff --git a/drivers/isdn/hardware/eicon/dadapter.h b/drivers/isdn/hardware/eicon/dadapter.h
deleted file mode 100644
index 5540f46a5be3..000000000000
--- a/drivers/isdn/hardware/eicon/dadapter.h
+++ /dev/null
@@ -1,34 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_DIDD_DADAPTER_INC__
27#define __DIVA_DIDD_DADAPTER_INC__
28
29void diva_didd_load_time_init(void);
30void diva_didd_load_time_finit(void);
31
32#define NEW_MAX_DESCRIPTORS 64
33
34#endif
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
deleted file mode 100644
index 301788115c4f..000000000000
--- a/drivers/isdn/hardware/eicon/debug.c
+++ /dev/null
@@ -1,2128 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2#include "platform.h"
3#include "pc.h"
4#include "di_defs.h"
5#include "debug_if.h"
6#include "divasync.h"
7#include "kst_ifc.h"
8#include "maintidi.h"
9#include "man_defs.h"
10
11/*
12 LOCALS
13*/
14#define DBG_MAGIC (0x47114711L)
15
16static void DI_register(void *arg);
17static void DI_deregister(pDbgHandle hDbg);
18static void DI_format(int do_lock, word id, int type, char *format, va_list argument_list);
19static void DI_format_locked(word id, int type, char *format, va_list argument_list);
20static void DI_format_old(word id, char *format, va_list ap) { }
21static void DiProcessEventLog(unsigned short id, unsigned long msgID, va_list ap) { }
22static void single_p(byte *P, word *PLength, byte Id);
23static void diva_maint_xdi_cb(ENTITY *e);
24static word SuperTraceCreateReadReq(byte *P, const char *path);
25static int diva_mnt_cmp_nmbr(const char *nmbr);
26static void diva_free_dma_descriptor(IDI_CALL request, int nr);
27static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic);
28void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);
29
30static dword MaxDumpSize = 256;
31static dword MaxXlogSize = 2 + 128;
32static char TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH + 1];
33static int TraceFilterIdent = -1;
34static int TraceFilterChannel = -1;
35
36typedef struct _diva_maint_client {
37 dword sec;
38 dword usec;
39 pDbgHandle hDbg;
40 char drvName[128];
41 dword dbgMask;
42 dword last_dbgMask;
43 IDI_CALL request;
44 _DbgHandle_ Dbg;
45 int logical;
46 int channels;
47 diva_strace_library_interface_t *pIdiLib;
48 BUFFERS XData;
49 char xbuffer[2048 + 512];
50 byte *pmem;
51 int request_pending;
52 int dma_handle;
53} diva_maint_client_t;
54static diva_maint_client_t clients[MAX_DESCRIPTORS];
55
56static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask);
57
58static void diva_maint_error(void *user_context,
59 diva_strace_library_interface_t *hLib,
60 int Adapter,
61 int error,
62 const char *file,
63 int line);
64static void diva_maint_state_change_notify(void *user_context,
65 diva_strace_library_interface_t *hLib,
66 int Adapter,
67 diva_trace_line_state_t *channel,
68 int notify_subject);
69static void diva_maint_trace_notify(void *user_context,
70 diva_strace_library_interface_t *hLib,
71 int Adapter,
72 void *xlog_buffer,
73 int length);
74
75
76
77typedef struct MSG_QUEUE {
78 dword Size; /* total size of queue (constant) */
79 byte *Base; /* lowest address (constant) */
80 byte *High; /* Base + Size (constant) */
81 byte *Head; /* first message in queue (if any) */
82 byte *Tail; /* first free position */
83 byte *Wrap; /* current wraparound position */
84 dword Count; /* current no of bytes in queue */
85} MSG_QUEUE;
86
87typedef struct MSG_HEAD {
88 volatile dword Size; /* size of data following MSG_HEAD */
89#define MSG_INCOMPLETE 0x8000 /* ored to Size until queueCompleteMsg */
90} MSG_HEAD;
91
92#define queueCompleteMsg(p) do { ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; } while (0)
93#define queueCount(q) ((q)->Count)
94#define MSG_NEED(size) \
95 ((sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1))
96
97static void queueInit(MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) {
98 Q->Size = sizeBuffer;
99 Q->Base = Q->Head = Q->Tail = Buffer;
100 Q->High = Buffer + sizeBuffer;
101 Q->Wrap = NULL;
102 Q->Count = 0;
103}
104
105static byte *queueAllocMsg(MSG_QUEUE *Q, word size) {
106 /* Allocate 'size' bytes at tail of queue which will be filled later
107 * directly with callers own message header info and/or message.
108 * An 'alloced' message is marked incomplete by oring the 'Size' field
109 * with MSG_INCOMPLETE.
110 * This must be reset via queueCompleteMsg() after the message is filled.
111 * As long as a message is marked incomplete queuePeekMsg() will return
112 * a 'queue empty' condition when it reaches such a message. */
113
114 MSG_HEAD *Msg;
115 word need = MSG_NEED(size);
116
117 if (Q->Tail == Q->Head) {
118 if (Q->Wrap || need > Q->Size) {
119 return NULL; /* full */
120 }
121 goto alloc; /* empty */
122 }
123
124 if (Q->Tail > Q->Head) {
125 if (Q->Tail + need <= Q->High) goto alloc; /* append */
126 if (Q->Base + need > Q->Head) {
127 return NULL; /* too much */
128 }
129 /* wraparound the queue (but not the message) */
130 Q->Wrap = Q->Tail;
131 Q->Tail = Q->Base;
132 goto alloc;
133 }
134
135 if (Q->Tail + need > Q->Head) {
136 return NULL; /* too much */
137 }
138
139alloc:
140 Msg = (MSG_HEAD *)Q->Tail;
141
142 Msg->Size = size | MSG_INCOMPLETE;
143
144 Q->Tail += need;
145 Q->Count += size;
146
147
148
149 return ((byte *)(Msg + 1));
150}
151
152static void queueFreeMsg(MSG_QUEUE *Q) {
153/* Free the message at head of queue */
154
155 word size = ((MSG_HEAD *)Q->Head)->Size & ~MSG_INCOMPLETE;
156
157 Q->Head += MSG_NEED(size);
158 Q->Count -= size;
159
160 if (Q->Wrap) {
161 if (Q->Head >= Q->Wrap) {
162 Q->Head = Q->Base;
163 Q->Wrap = NULL;
164 }
165 } else if (Q->Head >= Q->Tail) {
166 Q->Head = Q->Tail = Q->Base;
167 }
168}
169
170static byte *queuePeekMsg(MSG_QUEUE *Q, word *size) {
171 /* Show the first valid message in queue BUT DON'T free the message.
172 * After looking on the message contents it can be freed queueFreeMsg()
173 * or simply remain in message queue. */
174
175 MSG_HEAD *Msg = (MSG_HEAD *)Q->Head;
176
177 if (((byte *)Msg == Q->Tail && !Q->Wrap) ||
178 (Msg->Size & MSG_INCOMPLETE)) {
179 return NULL;
180 } else {
181 *size = Msg->Size;
182 return ((byte *)(Msg + 1));
183 }
184}
185
186/*
187 Message queue header
188*/
189static MSG_QUEUE *dbg_queue;
190static byte *dbg_base;
191static int external_dbg_queue;
192static diva_os_spin_lock_t dbg_q_lock;
193static diva_os_spin_lock_t dbg_adapter_lock;
194static int dbg_q_busy;
195static volatile dword dbg_sequence;
196
197/*
198 INTERFACE:
199 Initialize run time queue structures.
200 base: base of the message queue
201 length: length of the message queue
202 do_init: perfor queue reset
203
204 return: zero on success, -1 on error
205*/
206int diva_maint_init(byte *base, unsigned long length, int do_init) {
207 if (dbg_queue || (!base) || (length < (4096 * 4))) {
208 return (-1);
209 }
210
211 TraceFilter[0] = 0;
212 TraceFilterIdent = -1;
213 TraceFilterChannel = -1;
214
215 dbg_base = base;
216
217 *(dword *)base = (dword)DBG_MAGIC; /* Store Magic */
218 base += sizeof(dword);
219 length -= sizeof(dword);
220
221 *(dword *)base = 2048; /* Extension Field Length */
222 base += sizeof(dword);
223 length -= sizeof(dword);
224
225 strcpy(base, "KERNEL MODE BUFFER\n");
226 base += 2048;
227 length -= 2048;
228
229 *(dword *)base = 0; /* Terminate extension */
230 base += sizeof(dword);
231 length -= sizeof(dword);
232
233 *(void **)base = (void *)(base + sizeof(void *)); /* Store Base */
234 base += sizeof(void *);
235 length -= sizeof(void *);
236
237 dbg_queue = (MSG_QUEUE *)base;
238 queueInit(dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512);
239 external_dbg_queue = 0;
240
241 if (!do_init) {
242 external_dbg_queue = 1; /* memory was located on the external device */
243 }
244
245
246 if (diva_os_initialize_spin_lock(&dbg_q_lock, "dbg_init")) {
247 dbg_queue = NULL;
248 dbg_base = NULL;
249 external_dbg_queue = 0;
250 return (-1);
251 }
252
253 if (diva_os_initialize_spin_lock(&dbg_adapter_lock, "dbg_init")) {
254 diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init");
255 dbg_queue = NULL;
256 dbg_base = NULL;
257 external_dbg_queue = 0;
258 return (-1);
259 }
260
261 return (0);
262}
263
264/*
265 INTERFACE:
266 Finit at unload time
267 return address of internal queue or zero if queue
268 was external
269*/
270void *diva_maint_finit(void) {
271 void *ret = (void *)dbg_base;
272 int i;
273
274 dbg_queue = NULL;
275 dbg_base = NULL;
276
277 if (ret) {
278 diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit");
279 diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit");
280 }
281
282 if (external_dbg_queue) {
283 ret = NULL;
284 }
285 external_dbg_queue = 0;
286
287 for (i = 1; i < ARRAY_SIZE(clients); i++) {
288 if (clients[i].pmem) {
289 diva_os_free(0, clients[i].pmem);
290 }
291 }
292
293 return (ret);
294}
295
296/*
297 INTERFACE:
298 Return amount of messages in debug queue
299*/
300dword diva_dbg_q_length(void) {
301 return (dbg_queue ? queueCount(dbg_queue) : 0);
302}
303
304/*
305 INTERFACE:
306 Lock message queue and return the pointer to the first
307 entry.
308*/
309diva_dbg_entry_head_t *diva_maint_get_message(word *size,
310 diva_os_spin_lock_magic_t *old_irql) {
311 diva_dbg_entry_head_t *pmsg = NULL;
312
313 diva_os_enter_spin_lock(&dbg_q_lock, old_irql, "read");
314 if (dbg_q_busy) {
315 diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_busy");
316 return NULL;
317 }
318 dbg_q_busy = 1;
319
320 if (!(pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, size))) {
321 dbg_q_busy = 0;
322 diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_empty");
323 }
324
325 return (pmsg);
326}
327
328/*
329 INTERFACE:
330 acknowledge last message and unlock queue
331*/
332void diva_maint_ack_message(int do_release,
333 diva_os_spin_lock_magic_t *old_irql) {
334 if (!dbg_q_busy) {
335 return;
336 }
337 if (do_release) {
338 queueFreeMsg(dbg_queue);
339 }
340 dbg_q_busy = 0;
341 diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_ack");
342}
343
344
345/*
346 INTERFACE:
347 PRT COMP function used to register
348 with MAINT adapter or log in compatibility
349 mode in case older driver version is connected too
350*/
351void diva_maint_prtComp(char *format, ...) {
352 void *hDbg;
353 va_list ap;
354
355 if (!format)
356 return;
357
358 va_start(ap, format);
359
360 /*
361 register to new log driver functions
362 */
363 if ((format[0] == 0) && ((unsigned char)format[1] == 255)) {
364 hDbg = va_arg(ap, void *); /* ptr to DbgHandle */
365 DI_register(hDbg);
366 }
367
368 va_end(ap);
369}
370
371static void DI_register(void *arg) {
372 diva_os_spin_lock_magic_t old_irql;
373 dword sec, usec;
374 pDbgHandle hDbg;
375 int id, free_id = -1, best_id = 0;
376
377 diva_os_get_time(&sec, &usec);
378
379 hDbg = (pDbgHandle)arg;
380 /*
381 Check for bad args, specially for the old obsolete debug handle
382 */
383 if ((hDbg == NULL) ||
384 ((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) ||
385 (hDbg->Registered != 0)) {
386 return;
387 }
388
389 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register");
390
391 for (id = 1; id < ARRAY_SIZE(clients); id++) {
392 if (clients[id].hDbg == hDbg) {
393 /*
394 driver already registered
395 */
396 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
397 return;
398 }
399 if (clients[id].hDbg) { /* slot is busy */
400 continue;
401 }
402 free_id = id;
403 if (!strcmp(clients[id].drvName, hDbg->drvName)) {
404 /*
405 This driver was already registered with this name
406 and slot is still free - reuse it
407 */
408 best_id = 1;
409 break;
410 }
411 if (!clients[id].hDbg) { /* slot is busy */
412 break;
413 }
414 }
415
416 if (free_id != -1) {
417 diva_dbg_entry_head_t *pmsg = NULL;
418 int len;
419 char tmp[256];
420 word size;
421
422 /*
423 Register new driver with id == free_id
424 */
425 clients[free_id].hDbg = hDbg;
426 clients[free_id].sec = sec;
427 clients[free_id].usec = usec;
428 strcpy(clients[free_id].drvName, hDbg->drvName);
429
430 clients[free_id].dbgMask = hDbg->dbgMask;
431 if (best_id) {
432 hDbg->dbgMask |= clients[free_id].last_dbgMask;
433 } else {
434 clients[free_id].last_dbgMask = 0;
435 }
436
437 hDbg->Registered = DBG_HANDLE_REG_NEW;
438 hDbg->id = (byte)free_id;
439 hDbg->dbg_end = DI_deregister;
440 hDbg->dbg_prt = DI_format_locked;
441 hDbg->dbg_ev = DiProcessEventLog;
442 hDbg->dbg_irq = DI_format_locked;
443 if (hDbg->Version > 0) {
444 hDbg->dbg_old = DI_format_old;
445 }
446 hDbg->next = (pDbgHandle)DBG_MAGIC;
447
448 /*
449 Log driver register, MAINT driver ID is '0'
450 */
451 len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered",
452 free_id, hDbg->drvName);
453
454 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
455 (word)(len + 1 + sizeof(*pmsg))))) {
456 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
457 queueFreeMsg(dbg_queue);
458 } else {
459 break;
460 }
461 }
462
463 if (pmsg) {
464 pmsg->sequence = dbg_sequence++;
465 pmsg->time_sec = sec;
466 pmsg->time_usec = usec;
467 pmsg->facility = MSG_TYPE_STRING;
468 pmsg->dli = DLI_REG;
469 pmsg->drv_id = 0; /* id 0 - DIMAINT */
470 pmsg->di_cpu = 0;
471 pmsg->data_length = len + 1;
472
473 memcpy(&pmsg[1], tmp, len + 1);
474 queueCompleteMsg(pmsg);
475 diva_maint_wakeup_read();
476 }
477 }
478
479 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
480}
481
482static void DI_deregister(pDbgHandle hDbg) {
483 diva_os_spin_lock_magic_t old_irql, old_irql1;
484 dword sec, usec;
485 int i;
486 word size;
487 byte *pmem = NULL;
488
489 diva_os_get_time(&sec, &usec);
490
491 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read");
492 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read");
493
494 for (i = 1; i < ARRAY_SIZE(clients); i++) {
495 if (clients[i].hDbg == hDbg) {
496 diva_dbg_entry_head_t *pmsg;
497 char tmp[256];
498 int len;
499
500 clients[i].hDbg = NULL;
501
502 hDbg->id = -1;
503 hDbg->dbgMask = 0;
504 hDbg->dbg_end = NULL;
505 hDbg->dbg_prt = NULL;
506 hDbg->dbg_irq = NULL;
507 if (hDbg->Version > 0)
508 hDbg->dbg_old = NULL;
509 hDbg->Registered = 0;
510 hDbg->next = NULL;
511
512 if (clients[i].pIdiLib) {
513 (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
514 clients[i].pIdiLib = NULL;
515
516 pmem = clients[i].pmem;
517 clients[i].pmem = NULL;
518 }
519
520 /*
521 Log driver register, MAINT driver ID is '0'
522 */
523 len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered",
524 i, hDbg->drvName);
525
526 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
527 (word)(len + 1 + sizeof(*pmsg))))) {
528 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
529 queueFreeMsg(dbg_queue);
530 } else {
531 break;
532 }
533 }
534
535 if (pmsg) {
536 pmsg->sequence = dbg_sequence++;
537 pmsg->time_sec = sec;
538 pmsg->time_usec = usec;
539 pmsg->facility = MSG_TYPE_STRING;
540 pmsg->dli = DLI_REG;
541 pmsg->drv_id = 0; /* id 0 - DIMAINT */
542 pmsg->di_cpu = 0;
543 pmsg->data_length = len + 1;
544
545 memcpy(&pmsg[1], tmp, len + 1);
546 queueCompleteMsg(pmsg);
547 diva_maint_wakeup_read();
548 }
549
550 break;
551 }
552 }
553
554 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack");
555 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack");
556
557 if (pmem) {
558 diva_os_free(0, pmem);
559 }
560}
561
562static void DI_format_locked(unsigned short id,
563 int type,
564 char *format,
565 va_list argument_list) {
566 DI_format(1, id, type, format, argument_list);
567}
568
569static void DI_format(int do_lock,
570 unsigned short id,
571 int type,
572 char *format,
573 va_list ap) {
574 diva_os_spin_lock_magic_t old_irql;
575 dword sec, usec;
576 diva_dbg_entry_head_t *pmsg = NULL;
577 dword length;
578 word size;
579 static char fmtBuf[MSG_FRAME_MAX_SIZE + sizeof(*pmsg) + 1];
580 char *data;
581 unsigned short code;
582
583 if (diva_os_in_irq()) {
584 dbg_sequence++;
585 return;
586 }
587
588 if ((!format) ||
589 ((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) {
590 return;
591 }
592
593
594
595 diva_os_get_time(&sec, &usec);
596
597 if (do_lock) {
598 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "format");
599 }
600
601 switch (type) {
602 case DLI_MXLOG:
603 case DLI_BLK:
604 case DLI_SEND:
605 case DLI_RECV:
606 if (!(length = va_arg(ap, unsigned long))) {
607 break;
608 }
609 if (length > MaxDumpSize) {
610 length = MaxDumpSize;
611 }
612 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
613 (word)length + sizeof(*pmsg)))) {
614 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
615 queueFreeMsg(dbg_queue);
616 } else {
617 break;
618 }
619 }
620 if (pmsg) {
621 memcpy(&pmsg[1], format, length);
622 pmsg->sequence = dbg_sequence++;
623 pmsg->time_sec = sec;
624 pmsg->time_usec = usec;
625 pmsg->facility = MSG_TYPE_BINARY;
626 pmsg->dli = type; /* DLI_XXX */
627 pmsg->drv_id = id; /* driver MAINT id */
628 pmsg->di_cpu = 0;
629 pmsg->data_length = length;
630 queueCompleteMsg(pmsg);
631 }
632 break;
633
634 case DLI_XLOG: {
635 byte *p;
636 data = va_arg(ap, char *);
637 code = (unsigned short)va_arg(ap, unsigned int);
638 length = (unsigned long)va_arg(ap, unsigned int);
639
640 if (length > MaxXlogSize)
641 length = MaxXlogSize;
642
643 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
644 (word)length + sizeof(*pmsg) + 2))) {
645 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
646 queueFreeMsg(dbg_queue);
647 } else {
648 break;
649 }
650 }
651 if (pmsg) {
652 p = (byte *)&pmsg[1];
653 p[0] = (char)(code);
654 p[1] = (char)(code >> 8);
655 if (data && length) {
656 memcpy(&p[2], &data[0], length);
657 }
658 length += 2;
659
660 pmsg->sequence = dbg_sequence++;
661 pmsg->time_sec = sec;
662 pmsg->time_usec = usec;
663 pmsg->facility = MSG_TYPE_BINARY;
664 pmsg->dli = type; /* DLI_XXX */
665 pmsg->drv_id = id; /* driver MAINT id */
666 pmsg->di_cpu = 0;
667 pmsg->data_length = length;
668 queueCompleteMsg(pmsg);
669 }
670 } break;
671
672 case DLI_LOG:
673 case DLI_FTL:
674 case DLI_ERR:
675 case DLI_TRC:
676 case DLI_REG:
677 case DLI_MEM:
678 case DLI_SPL:
679 case DLI_IRP:
680 case DLI_TIM:
681 case DLI_TAPI:
682 case DLI_NDIS:
683 case DLI_CONN:
684 case DLI_STAT:
685 case DLI_PRV0:
686 case DLI_PRV1:
687 case DLI_PRV2:
688 case DLI_PRV3:
689 if ((length = (unsigned long)vsprintf(&fmtBuf[0], format, ap)) > 0) {
690 length += (sizeof(*pmsg) + 1);
691
692 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
693 (word)length))) {
694 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
695 queueFreeMsg(dbg_queue);
696 } else {
697 break;
698 }
699 }
700
701 pmsg->sequence = dbg_sequence++;
702 pmsg->time_sec = sec;
703 pmsg->time_usec = usec;
704 pmsg->facility = MSG_TYPE_STRING;
705 pmsg->dli = type; /* DLI_XXX */
706 pmsg->drv_id = id; /* driver MAINT id */
707 pmsg->di_cpu = 0;
708 pmsg->data_length = length - sizeof(*pmsg);
709
710 memcpy(&pmsg[1], fmtBuf, pmsg->data_length);
711 queueCompleteMsg(pmsg);
712 }
713 break;
714
715 } /* switch type */
716
717
718 if (queueCount(dbg_queue)) {
719 diva_maint_wakeup_read();
720 }
721
722 if (do_lock) {
723 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "format");
724 }
725}
726
727/*
728 Write driver ID and driver revision to callers buffer
729*/
730int diva_get_driver_info(dword id, byte *data, int data_length) {
731 diva_os_spin_lock_magic_t old_irql;
732 byte *p = data;
733 int to_copy;
734
735 if (!data || !id || (data_length < 17) ||
736 (id >= ARRAY_SIZE(clients))) {
737 return (-1);
738 }
739
740 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info");
741
742 if (clients[id].hDbg) {
743 *p++ = 1;
744 *p++ = (byte)clients[id].sec; /* save seconds */
745 *p++ = (byte)(clients[id].sec >> 8);
746 *p++ = (byte)(clients[id].sec >> 16);
747 *p++ = (byte)(clients[id].sec >> 24);
748
749 *p++ = (byte)(clients[id].usec / 1000); /* save mseconds */
750 *p++ = (byte)((clients[id].usec / 1000) >> 8);
751 *p++ = (byte)((clients[id].usec / 1000) >> 16);
752 *p++ = (byte)((clients[id].usec / 1000) >> 24);
753
754 data_length -= 9;
755
756 if ((to_copy = min(strlen(clients[id].drvName), (size_t)(data_length - 1)))) {
757 memcpy(p, clients[id].drvName, to_copy);
758 p += to_copy;
759 data_length -= to_copy;
760 if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) {
761 *p++ = '(';
762 data_length -= 1;
763 if ((to_copy = min(strlen(clients[id].hDbg->drvTag), (size_t)(data_length - 2)))) {
764 memcpy(p, clients[id].hDbg->drvTag, to_copy);
765 p += to_copy;
766 data_length -= to_copy;
767 if (data_length >= 2) {
768 *p++ = ')';
769 data_length--;
770 }
771 }
772 }
773 }
774 }
775 *p++ = 0;
776
777 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info");
778
779 return (p - data);
780}
781
782int diva_get_driver_dbg_mask(dword id, byte *data) {
783 diva_os_spin_lock_magic_t old_irql;
784 int ret = -1;
785
786 if (!data || !id || (id >= ARRAY_SIZE(clients))) {
787 return (-1);
788 }
789 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info");
790
791 if (clients[id].hDbg) {
792 ret = 4;
793 *data++ = (byte)(clients[id].hDbg->dbgMask);
794 *data++ = (byte)(clients[id].hDbg->dbgMask >> 8);
795 *data++ = (byte)(clients[id].hDbg->dbgMask >> 16);
796 *data++ = (byte)(clients[id].hDbg->dbgMask >> 24);
797 }
798
799 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info");
800
801 return (ret);
802}
803
804int diva_set_driver_dbg_mask(dword id, dword mask) {
805 diva_os_spin_lock_magic_t old_irql, old_irql1;
806 int ret = -1;
807
808
809 if (!id || (id >= ARRAY_SIZE(clients))) {
810 return (-1);
811 }
812
813 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
814 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "dbg mask");
815
816 if (clients[id].hDbg) {
817 dword old_mask = clients[id].hDbg->dbgMask;
818 mask &= 0x7fffffff;
819 clients[id].hDbg->dbgMask = mask;
820 clients[id].last_dbgMask = (clients[id].hDbg->dbgMask | clients[id].dbgMask);
821 ret = 4;
822 diva_change_management_debug_mask(&clients[id], old_mask);
823 }
824
825
826 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "dbg mask");
827
828 if (clients[id].request_pending) {
829 clients[id].request_pending = 0;
830 (*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
831 }
832
833 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
834
835 return (ret);
836}
837
838static int diva_get_idi_adapter_info(IDI_CALL request, dword *serial, dword *logical) {
839 IDI_SYNC_REQ sync_req;
840
841 sync_req.xdi_logical_adapter_number.Req = 0;
842 sync_req.xdi_logical_adapter_number.Rc = IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;
843 (*request)((ENTITY *)&sync_req);
844 *logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number;
845
846 sync_req.GetSerial.Req = 0;
847 sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
848 sync_req.GetSerial.serial = 0;
849 (*request)((ENTITY *)&sync_req);
850 *serial = sync_req.GetSerial.serial;
851
852 return (0);
853}
854
855/*
856 Register XDI adapter as MAINT compatible driver
857*/
858void diva_mnt_add_xdi_adapter(const DESCRIPTOR *d) {
859 diva_os_spin_lock_magic_t old_irql, old_irql1;
860 dword sec, usec, logical, serial, org_mask;
861 int id, free_id = -1;
862 char tmp[128];
863 diva_dbg_entry_head_t *pmsg = NULL;
864 int len;
865 word size;
866 byte *pmem;
867
868 diva_os_get_time(&sec, &usec);
869 diva_get_idi_adapter_info(d->request, &serial, &logical);
870 if (serial & 0xff000000) {
871 sprintf(tmp, "ADAPTER:%d SN:%u-%d",
872 (int)logical,
873 serial & 0x00ffffff,
874 (byte)(((serial & 0xff000000) >> 24) + 1));
875 } else {
876 sprintf(tmp, "ADAPTER:%d SN:%u", (int)logical, serial);
877 }
878
879 if (!(pmem = diva_os_malloc(0, DivaSTraceGetMemotyRequirement(d->channels)))) {
880 return;
881 }
882 memset(pmem, 0x00, DivaSTraceGetMemotyRequirement(d->channels));
883
884 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
885 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register");
886
887 for (id = 1; id < ARRAY_SIZE(clients); id++) {
888 if (clients[id].hDbg && (clients[id].request == d->request)) {
889 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
890 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
891 diva_os_free(0, pmem);
892 return;
893 }
894 if (clients[id].hDbg) { /* slot is busy */
895 continue;
896 }
897 if (free_id < 0) {
898 free_id = id;
899 }
900 if (!strcmp(clients[id].drvName, tmp)) {
901 /*
902 This driver was already registered with this name
903 and slot is still free - reuse it
904 */
905 free_id = id;
906 break;
907 }
908 }
909
910 if (free_id < 0) {
911 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
912 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
913 diva_os_free(0, pmem);
914 return;
915 }
916
917 id = free_id;
918 clients[id].request = d->request;
919 clients[id].request_pending = 0;
920 clients[id].hDbg = &clients[id].Dbg;
921 clients[id].sec = sec;
922 clients[id].usec = usec;
923 strcpy(clients[id].drvName, tmp);
924 strcpy(clients[id].Dbg.drvName, tmp);
925 clients[id].Dbg.drvTag[0] = 0;
926 clients[id].logical = (int)logical;
927 clients[id].channels = (int)d->channels;
928 clients[id].dma_handle = -1;
929
930 clients[id].Dbg.dbgMask = 0;
931 clients[id].dbgMask = clients[id].Dbg.dbgMask;
932 if (id) {
933 clients[id].Dbg.dbgMask |= clients[free_id].last_dbgMask;
934 } else {
935 clients[id].last_dbgMask = 0;
936 }
937 clients[id].Dbg.Registered = DBG_HANDLE_REG_NEW;
938 clients[id].Dbg.id = (byte)id;
939 clients[id].Dbg.dbg_end = DI_deregister;
940 clients[id].Dbg.dbg_prt = DI_format_locked;
941 clients[id].Dbg.dbg_ev = DiProcessEventLog;
942 clients[id].Dbg.dbg_irq = DI_format_locked;
943 clients[id].Dbg.next = (pDbgHandle)DBG_MAGIC;
944
945 {
946 diva_trace_library_user_interface_t diva_maint_user_ifc = { &clients[id],
947 diva_maint_state_change_notify,
948 diva_maint_trace_notify,
949 diva_maint_error };
950
951 /*
952 Attach to adapter management interface
953 */
954 if ((clients[id].pIdiLib =
955 DivaSTraceLibraryCreateInstance((int)logical, &diva_maint_user_ifc, pmem))) {
956 if (((*(clients[id].pIdiLib->DivaSTraceLibraryStart))(clients[id].pIdiLib->hLib))) {
957 diva_mnt_internal_dprintf(0, DLI_ERR, "Adapter(%d) Start failed", (int)logical);
958 (*(clients[id].pIdiLib->DivaSTraceLibraryFinit))(clients[id].pIdiLib->hLib);
959 clients[id].pIdiLib = NULL;
960 }
961 } else {
962 diva_mnt_internal_dprintf(0, DLI_ERR, "A(%d) management init failed", (int)logical);
963 }
964 }
965
966 if (!clients[id].pIdiLib) {
967 clients[id].request = NULL;
968 clients[id].request_pending = 0;
969 clients[id].hDbg = NULL;
970 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
971 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
972 diva_os_free(0, pmem);
973 return;
974 }
975
976 /*
977 Log driver register, MAINT driver ID is '0'
978 */
979 len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered",
980 id, clients[id].Dbg.drvName);
981
982 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
983 (word)(len + 1 + sizeof(*pmsg))))) {
984 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
985 queueFreeMsg(dbg_queue);
986 } else {
987 break;
988 }
989 }
990
991 if (pmsg) {
992 pmsg->sequence = dbg_sequence++;
993 pmsg->time_sec = sec;
994 pmsg->time_usec = usec;
995 pmsg->facility = MSG_TYPE_STRING;
996 pmsg->dli = DLI_REG;
997 pmsg->drv_id = 0; /* id 0 - DIMAINT */
998 pmsg->di_cpu = 0;
999 pmsg->data_length = len + 1;
1000
1001 memcpy(&pmsg[1], tmp, len + 1);
1002 queueCompleteMsg(pmsg);
1003 diva_maint_wakeup_read();
1004 }
1005
1006 org_mask = clients[id].Dbg.dbgMask;
1007 clients[id].Dbg.dbgMask = 0;
1008
1009 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
1010
1011 if (clients[id].request_pending) {
1012 clients[id].request_pending = 0;
1013 (*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
1014 }
1015
1016 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
1017
1018 diva_set_driver_dbg_mask(id, org_mask);
1019}
1020
1021/*
1022 De-Register XDI adapter
1023*/
1024void diva_mnt_remove_xdi_adapter(const DESCRIPTOR *d) {
1025 diva_os_spin_lock_magic_t old_irql, old_irql1;
1026 dword sec, usec;
1027 int i;
1028 word size;
1029 byte *pmem = NULL;
1030
1031 diva_os_get_time(&sec, &usec);
1032
1033 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read");
1034 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read");
1035
1036 for (i = 1; i < ARRAY_SIZE(clients); i++) {
1037 if (clients[i].hDbg && (clients[i].request == d->request)) {
1038 diva_dbg_entry_head_t *pmsg;
1039 char tmp[256];
1040 int len;
1041
1042 if (clients[i].pIdiLib) {
1043 (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
1044 clients[i].pIdiLib = NULL;
1045
1046 pmem = clients[i].pmem;
1047 clients[i].pmem = NULL;
1048 }
1049
1050 clients[i].hDbg = NULL;
1051 clients[i].request_pending = 0;
1052 if (clients[i].dma_handle >= 0) {
1053 /*
1054 Free DMA handle
1055 */
1056 diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
1057 clients[i].dma_handle = -1;
1058 }
1059 clients[i].request = NULL;
1060
1061 /*
1062 Log driver register, MAINT driver ID is '0'
1063 */
1064 len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered",
1065 i, clients[i].Dbg.drvName);
1066
1067 memset(&clients[i].Dbg, 0x00, sizeof(clients[i].Dbg));
1068
1069 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
1070 (word)(len + 1 + sizeof(*pmsg))))) {
1071 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
1072 queueFreeMsg(dbg_queue);
1073 } else {
1074 break;
1075 }
1076 }
1077
1078 if (pmsg) {
1079 pmsg->sequence = dbg_sequence++;
1080 pmsg->time_sec = sec;
1081 pmsg->time_usec = usec;
1082 pmsg->facility = MSG_TYPE_STRING;
1083 pmsg->dli = DLI_REG;
1084 pmsg->drv_id = 0; /* id 0 - DIMAINT */
1085 pmsg->di_cpu = 0;
1086 pmsg->data_length = len + 1;
1087
1088 memcpy(&pmsg[1], tmp, len + 1);
1089 queueCompleteMsg(pmsg);
1090 diva_maint_wakeup_read();
1091 }
1092
1093 break;
1094 }
1095 }
1096
1097 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack");
1098 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack");
1099
1100 if (pmem) {
1101 diva_os_free(0, pmem);
1102 }
1103}
1104
1105/* ----------------------------------------------------------------
1106 Low level interface for management interface client
1107 ---------------------------------------------------------------- */
1108/*
1109 Return handle to client structure
1110*/
1111void *SuperTraceOpenAdapter(int AdapterNumber) {
1112 int i;
1113
1114 for (i = 1; i < ARRAY_SIZE(clients); i++) {
1115 if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) {
1116 return (&clients[i]);
1117 }
1118 }
1119
1120 return NULL;
1121}
1122
1123int SuperTraceCloseAdapter(void *AdapterHandle) {
1124 return (0);
1125}
1126
1127int SuperTraceReadRequest(void *AdapterHandle, const char *name, byte *data) {
1128 diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
1129
1130 if (pC && pC->pIdiLib && pC->request) {
1131 ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
1132 byte *xdata = (byte *)&pC->xbuffer[0];
1133 char tmp = 0;
1134 word length;
1135
1136 if (!strcmp(name, "\\")) { /* Read ROOT */
1137 name = &tmp;
1138 }
1139 length = SuperTraceCreateReadReq(xdata, name);
1140 single_p(xdata, &length, 0); /* End Of Message */
1141
1142 e->Req = MAN_READ;
1143 e->ReqCh = 0;
1144 e->X->PLength = length;
1145 e->X->P = (byte *)xdata;
1146
1147 pC->request_pending = 1;
1148
1149 return (0);
1150 }
1151
1152 return (-1);
1153}
1154
1155int SuperTraceGetNumberOfChannels(void *AdapterHandle) {
1156 if (AdapterHandle) {
1157 diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
1158
1159 return (pC->channels);
1160 }
1161
1162 return (0);
1163}
1164
1165int SuperTraceASSIGN(void *AdapterHandle, byte *data) {
1166 diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
1167
1168 if (pC && pC->pIdiLib && pC->request) {
1169 ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
1170 IDI_SYNC_REQ *preq;
1171 char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)];
1172 char features[4];
1173 word assign_data_length = 1;
1174
1175 features[0] = 0;
1176 pC->xbuffer[0] = 0;
1177 preq = (IDI_SYNC_REQ *)&buffer[0];
1178 preq->xdi_extended_features.Req = 0;
1179 preq->xdi_extended_features.Rc = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
1180 preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
1181 preq->xdi_extended_features.info.features = &features[0];
1182
1183 (*(pC->request))((ENTITY *)preq);
1184
1185 if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) &&
1186 (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) {
1187 dword uninitialized_var(rx_dma_magic);
1188 if ((pC->dma_handle = diva_get_dma_descriptor(pC->request, &rx_dma_magic)) >= 0) {
1189 pC->xbuffer[0] = LLI;
1190 pC->xbuffer[1] = 8;
1191 pC->xbuffer[2] = 0x40;
1192 pC->xbuffer[3] = (byte)pC->dma_handle;
1193 pC->xbuffer[4] = (byte)rx_dma_magic;
1194 pC->xbuffer[5] = (byte)(rx_dma_magic >> 8);
1195 pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
1196 pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
1197 pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
1198 pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
1199 pC->xbuffer[10] = 0;
1200
1201 assign_data_length = 11;
1202 }
1203 } else {
1204 pC->dma_handle = -1;
1205 }
1206
1207 e->Id = MAN_ID;
1208 e->callback = diva_maint_xdi_cb;
1209 e->XNum = 1;
1210 e->X = &pC->XData;
1211 e->Req = ASSIGN;
1212 e->ReqCh = 0;
1213 e->X->PLength = assign_data_length;
1214 e->X->P = (byte *)&pC->xbuffer[0];
1215
1216 pC->request_pending = 1;
1217
1218 return (0);
1219 }
1220
1221 return (-1);
1222}
1223
1224int SuperTraceREMOVE(void *AdapterHandle) {
1225 diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
1226
1227 if (pC && pC->pIdiLib && pC->request) {
1228 ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
1229
1230 e->XNum = 1;
1231 e->X = &pC->XData;
1232 e->Req = REMOVE;
1233 e->ReqCh = 0;
1234 e->X->PLength = 1;
1235 e->X->P = (byte *)&pC->xbuffer[0];
1236 pC->xbuffer[0] = 0;
1237
1238 pC->request_pending = 1;
1239
1240 return (0);
1241 }
1242
1243 return (-1);
1244}
1245
1246int SuperTraceTraceOnRequest(void *hAdapter, const char *name, byte *data) {
1247 diva_maint_client_t *pC = (diva_maint_client_t *)hAdapter;
1248
1249 if (pC && pC->pIdiLib && pC->request) {
1250 ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
1251 byte *xdata = (byte *)&pC->xbuffer[0];
1252 char tmp = 0;
1253 word length;
1254
1255 if (!strcmp(name, "\\")) { /* Read ROOT */
1256 name = &tmp;
1257 }
1258 length = SuperTraceCreateReadReq(xdata, name);
1259 single_p(xdata, &length, 0); /* End Of Message */
1260 e->Req = MAN_EVENT_ON;
1261 e->ReqCh = 0;
1262 e->X->PLength = length;
1263 e->X->P = (byte *)xdata;
1264
1265 pC->request_pending = 1;
1266
1267 return (0);
1268 }
1269
1270 return (-1);
1271}
1272
1273int SuperTraceWriteVar(void *AdapterHandle,
1274 byte *data,
1275 const char *name,
1276 void *var,
1277 byte type,
1278 byte var_length) {
1279 diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
1280
1281 if (pC && pC->pIdiLib && pC->request) {
1282 ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
1283 diva_man_var_header_t *pVar = (diva_man_var_header_t *)&pC->xbuffer[0];
1284 word length = SuperTraceCreateReadReq((byte *)pVar, name);
1285
1286 memcpy(&pC->xbuffer[length], var, var_length);
1287 length += var_length;
1288 pVar->length += var_length;
1289 pVar->value_length = var_length;
1290 pVar->type = type;
1291 single_p((byte *)pVar, &length, 0); /* End Of Message */
1292
1293 e->Req = MAN_WRITE;
1294 e->ReqCh = 0;
1295 e->X->PLength = length;
1296 e->X->P = (byte *)pVar;
1297
1298 pC->request_pending = 1;
1299
1300 return (0);
1301 }
1302
1303 return (-1);
1304}
1305
1306int SuperTraceExecuteRequest(void *AdapterHandle,
1307 const char *name,
1308 byte *data) {
1309 diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
1310
1311 if (pC && pC->pIdiLib && pC->request) {
1312 ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
1313 byte *xdata = (byte *)&pC->xbuffer[0];
1314 word length;
1315
1316 length = SuperTraceCreateReadReq(xdata, name);
1317 single_p(xdata, &length, 0); /* End Of Message */
1318
1319 e->Req = MAN_EXECUTE;
1320 e->ReqCh = 0;
1321 e->X->PLength = length;
1322 e->X->P = (byte *)xdata;
1323
1324 pC->request_pending = 1;
1325
1326 return (0);
1327 }
1328
1329 return (-1);
1330}
1331
1332static word SuperTraceCreateReadReq(byte *P, const char *path) {
1333 byte var_length;
1334 byte *plen;
1335
1336 var_length = (byte)strlen(path);
1337
1338 *P++ = ESC;
1339 plen = P++;
1340 *P++ = 0x80; /* MAN_IE */
1341 *P++ = 0x00; /* Type */
1342 *P++ = 0x00; /* Attribute */
1343 *P++ = 0x00; /* Status */
1344 *P++ = 0x00; /* Variable Length */
1345 *P++ = var_length;
1346 memcpy(P, path, var_length);
1347 P += var_length;
1348 *plen = var_length + 0x06;
1349
1350 return ((word)(var_length + 0x08));
1351}
1352
1353static void single_p(byte *P, word *PLength, byte Id) {
1354 P[(*PLength)++] = Id;
1355}
1356
1357static void diva_maint_xdi_cb(ENTITY *e) {
1358 diva_strace_context_t *pLib = DIVAS_CONTAINING_RECORD(e, diva_strace_context_t, e);
1359 diva_maint_client_t *pC;
1360 diva_os_spin_lock_magic_t old_irql, old_irql1;
1361
1362
1363 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb");
1364 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb");
1365
1366 pC = (diva_maint_client_t *)pLib->hAdapter;
1367
1368 if ((e->complete == 255) || (pC->dma_handle < 0)) {
1369 if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
1370 diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error");
1371 }
1372 } else {
1373 /*
1374 Process combined management interface indication
1375 */
1376 if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
1377 diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error (DMA mode)");
1378 }
1379 }
1380
1381 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb");
1382
1383
1384 if (pC->request_pending) {
1385 pC->request_pending = 0;
1386 (*(pC->request))(e);
1387 }
1388
1389 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb");
1390}
1391
1392
1393static void diva_maint_error(void *user_context,
1394 diva_strace_library_interface_t *hLib,
1395 int Adapter,
1396 int error,
1397 const char *file,
1398 int line) {
1399 diva_mnt_internal_dprintf(0, DLI_ERR,
1400 "Trace library error(%d) A(%d) %s %d", error, Adapter, file, line);
1401}
1402
1403static void print_ie(diva_trace_ie_t *ie, char *buffer, int length) {
1404 int i;
1405
1406 buffer[0] = 0;
1407
1408 if (length > 32) {
1409 for (i = 0; ((i < ie->length) && (length > 3)); i++) {
1410 sprintf(buffer, "%02x", ie->data[i]);
1411 buffer += 2;
1412 length -= 2;
1413 if (i < (ie->length - 1)) {
1414 strcpy(buffer, " ");
1415 buffer++;
1416 length--;
1417 }
1418 }
1419 }
1420}
1421
1422static void diva_maint_state_change_notify(void *user_context,
1423 diva_strace_library_interface_t *hLib,
1424 int Adapter,
1425 diva_trace_line_state_t *channel,
1426 int notify_subject) {
1427 diva_maint_client_t *pC = (diva_maint_client_t *)user_context;
1428 diva_trace_fax_state_t *fax = &channel->fax;
1429 diva_trace_modem_state_t *modem = &channel->modem;
1430 char tmp[256];
1431
1432 if (!pC->hDbg) {
1433 return;
1434 }
1435
1436 switch (notify_subject) {
1437 case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE: {
1438 int view = (TraceFilter[0] == 0);
1439 /*
1440 Process selective Trace
1441 */
1442 if (channel->Line[0] == 'I' && channel->Line[1] == 'd' &&
1443 channel->Line[2] == 'l' && channel->Line[3] == 'e') {
1444 if ((TraceFilterIdent == pC->hDbg->id) && (TraceFilterChannel == (int)channel->ChannelNumber)) {
1445 (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 0);
1446 (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 0);
1447 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace OFF for Ch=%d",
1448 (int)channel->ChannelNumber);
1449 TraceFilterIdent = -1;
1450 TraceFilterChannel = -1;
1451 view = 1;
1452 }
1453 } else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr(&channel->RemoteAddress[0]) &&
1454 diva_mnt_cmp_nmbr(&channel->LocalAddress[0]))) {
1455
1456 if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0) { /* Activate B-channel trace */
1457 (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 1);
1458 }
1459 if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0) { /* Activate AudioTap Trace */
1460 (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 1);
1461 }
1462
1463 TraceFilterIdent = pC->hDbg->id;
1464 TraceFilterChannel = (int)channel->ChannelNumber;
1465
1466 if (TraceFilterIdent >= 0) {
1467 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace ON for Ch=%d",
1468 (int)channel->ChannelNumber);
1469 view = 1;
1470 }
1471 }
1472 if (view && (pC->hDbg->dbgMask & DIVA_MGT_DBG_LINE_EVENTS)) {
1473 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Ch = %d",
1474 (int)channel->ChannelNumber);
1475 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Status = <%s>", &channel->Line[0]);
1476 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer1 = <%s>", &channel->Framing[0]);
1477 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer2 = <%s>", &channel->Layer2[0]);
1478 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer3 = <%s>", &channel->Layer3[0]);
1479 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RAddr = <%s>",
1480 &channel->RemoteAddress[0]);
1481 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RSAddr = <%s>",
1482 &channel->RemoteSubAddress[0]);
1483 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LAddr = <%s>",
1484 &channel->LocalAddress[0]);
1485 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LSAddr = <%s>",
1486 &channel->LocalSubAddress[0]);
1487 print_ie(&channel->call_BC, tmp, sizeof(tmp));
1488 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L BC = <%s>", tmp);
1489 print_ie(&channel->call_HLC, tmp, sizeof(tmp));
1490 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L HLC = <%s>", tmp);
1491 print_ie(&channel->call_LLC, tmp, sizeof(tmp));
1492 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LLC = <%s>", tmp);
1493 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L CR = 0x%x", channel->CallReference);
1494 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Disc = 0x%x",
1495 channel->LastDisconnecCause);
1496 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Owner = <%s>", &channel->UserID[0]);
1497 }
1498
1499 } break;
1500
1501 case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE:
1502 if (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_PROGRESS) {
1503 {
1504 int ch = TraceFilterChannel;
1505 int id = TraceFilterIdent;
1506
1507 if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
1508 (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
1509 if (ch != (int)modem->ChannelNumber) {
1510 break;
1511 }
1512 } else if (TraceFilter[0] != 0) {
1513 break;
1514 }
1515 }
1516
1517
1518 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Ch = %lu",
1519 (int)modem->ChannelNumber);
1520 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Event = %lu", modem->Event);
1521 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Norm = %lu", modem->Norm);
1522 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Opts. = 0x%08x", modem->Options);
1523 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Tx = %lu Bps", modem->TxSpeed);
1524 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rx = %lu Bps", modem->RxSpeed);
1525 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RT = %lu mSec",
1526 modem->RoundtripMsec);
1527 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Sr = %lu", modem->SymbolRate);
1528 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rxl = %d dBm", modem->RxLeveldBm);
1529 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM El = %d dBm", modem->EchoLeveldBm);
1530 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM SNR = %lu dB", modem->SNRdb);
1531 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM MAE = %lu", modem->MAE);
1532 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRet = %lu",
1533 modem->LocalRetrains);
1534 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRet = %lu",
1535 modem->RemoteRetrains);
1536 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRes = %lu", modem->LocalResyncs);
1537 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRes = %lu",
1538 modem->RemoteResyncs);
1539 if (modem->Event == 3) {
1540 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Disc = %lu", modem->DiscReason);
1541 }
1542 }
1543 if ((modem->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_STATISTICS)) {
1544 (*(pC->pIdiLib->DivaSTraceGetModemStatistics))(pC->pIdiLib);
1545 }
1546 break;
1547
1548 case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE:
1549 if (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_PROGRESS) {
1550 {
1551 int ch = TraceFilterChannel;
1552 int id = TraceFilterIdent;
1553
1554 if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
1555 (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
1556 if (ch != (int)fax->ChannelNumber) {
1557 break;
1558 }
1559 } else if (TraceFilter[0] != 0) {
1560 break;
1561 }
1562 }
1563
1564 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Ch = %lu", (int)fax->ChannelNumber);
1565 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Event = %lu", fax->Event);
1566 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pages = %lu", fax->Page_Counter);
1567 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Feat. = 0x%08x", fax->Features);
1568 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX ID = <%s>", &fax->Station_ID[0]);
1569 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Saddr = <%s>", &fax->Subaddress[0]);
1570 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pwd = <%s>", &fax->Password[0]);
1571 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Speed = %lu", fax->Speed);
1572 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Res. = 0x%08x", fax->Resolution);
1573 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Width = %lu", fax->Paper_Width);
1574 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Length= %lu", fax->Paper_Length);
1575 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX SLT = %lu", fax->Scanline_Time);
1576 if (fax->Event == 3) {
1577 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Disc = %lu", fax->Disc_Reason);
1578 }
1579 }
1580 if ((fax->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_STATISTICS)) {
1581 (*(pC->pIdiLib->DivaSTraceGetFaxStatistics))(pC->pIdiLib);
1582 }
1583 break;
1584
1585 case DIVA_SUPER_TRACE_INTERFACE_CHANGE:
1586 if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_EVENTS) {
1587 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT,
1588 "Layer 1 -> [%s]", channel->pInterface->Layer1);
1589 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT,
1590 "Layer 2 -> [%s]", channel->pInterface->Layer2);
1591 }
1592 break;
1593
1594 case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:
1595 if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {
1596 /*
1597 Incoming Statistics
1598 */
1599 if (channel->pInterfaceStat->inc.Calls) {
1600 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1601 "Inc Calls =%lu", channel->pInterfaceStat->inc.Calls);
1602 }
1603 if (channel->pInterfaceStat->inc.Connected) {
1604 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1605 "Inc Connected =%lu", channel->pInterfaceStat->inc.Connected);
1606 }
1607 if (channel->pInterfaceStat->inc.User_Busy) {
1608 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1609 "Inc Busy =%lu", channel->pInterfaceStat->inc.User_Busy);
1610 }
1611 if (channel->pInterfaceStat->inc.Call_Rejected) {
1612 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1613 "Inc Rejected =%lu", channel->pInterfaceStat->inc.Call_Rejected);
1614 }
1615 if (channel->pInterfaceStat->inc.Wrong_Number) {
1616 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1617 "Inc Wrong Nr =%lu", channel->pInterfaceStat->inc.Wrong_Number);
1618 }
1619 if (channel->pInterfaceStat->inc.Incompatible_Dst) {
1620 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1621 "Inc Incomp. Dest =%lu", channel->pInterfaceStat->inc.Incompatible_Dst);
1622 }
1623 if (channel->pInterfaceStat->inc.Out_of_Order) {
1624 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1625 "Inc Out of Order =%lu", channel->pInterfaceStat->inc.Out_of_Order);
1626 }
1627 if (channel->pInterfaceStat->inc.Ignored) {
1628 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1629 "Inc Ignored =%lu", channel->pInterfaceStat->inc.Ignored);
1630 }
1631
1632 /*
1633 Outgoing Statistics
1634 */
1635 if (channel->pInterfaceStat->outg.Calls) {
1636 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1637 "Outg Calls =%lu", channel->pInterfaceStat->outg.Calls);
1638 }
1639 if (channel->pInterfaceStat->outg.Connected) {
1640 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1641 "Outg Connected =%lu", channel->pInterfaceStat->outg.Connected);
1642 }
1643 if (channel->pInterfaceStat->outg.User_Busy) {
1644 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1645 "Outg Busy =%lu", channel->pInterfaceStat->outg.User_Busy);
1646 }
1647 if (channel->pInterfaceStat->outg.No_Answer) {
1648 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1649 "Outg No Answer =%lu", channel->pInterfaceStat->outg.No_Answer);
1650 }
1651 if (channel->pInterfaceStat->outg.Wrong_Number) {
1652 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1653 "Outg Wrong Nr =%lu", channel->pInterfaceStat->outg.Wrong_Number);
1654 }
1655 if (channel->pInterfaceStat->outg.Call_Rejected) {
1656 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1657 "Outg Rejected =%lu", channel->pInterfaceStat->outg.Call_Rejected);
1658 }
1659 if (channel->pInterfaceStat->outg.Other_Failures) {
1660 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1661 "Outg Other Failures =%lu", channel->pInterfaceStat->outg.Other_Failures);
1662 }
1663 }
1664 break;
1665
1666 case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE:
1667 if (channel->pInterfaceStat->mdm.Disc_Normal) {
1668 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1669 "MDM Disc Normal = %lu", channel->pInterfaceStat->mdm.Disc_Normal);
1670 }
1671 if (channel->pInterfaceStat->mdm.Disc_Unspecified) {
1672 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1673 "MDM Disc Unsp. = %lu", channel->pInterfaceStat->mdm.Disc_Unspecified);
1674 }
1675 if (channel->pInterfaceStat->mdm.Disc_Busy_Tone) {
1676 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1677 "MDM Disc Busy Tone = %lu", channel->pInterfaceStat->mdm.Disc_Busy_Tone);
1678 }
1679 if (channel->pInterfaceStat->mdm.Disc_Congestion) {
1680 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1681 "MDM Disc Congestion = %lu", channel->pInterfaceStat->mdm.Disc_Congestion);
1682 }
1683 if (channel->pInterfaceStat->mdm.Disc_Carr_Wait) {
1684 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1685 "MDM Disc Carrier Wait = %lu", channel->pInterfaceStat->mdm.Disc_Carr_Wait);
1686 }
1687 if (channel->pInterfaceStat->mdm.Disc_Trn_Timeout) {
1688 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1689 "MDM Disc Trn. T.o. = %lu", channel->pInterfaceStat->mdm.Disc_Trn_Timeout);
1690 }
1691 if (channel->pInterfaceStat->mdm.Disc_Incompat) {
1692 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1693 "MDM Disc Incompatible = %lu", channel->pInterfaceStat->mdm.Disc_Incompat);
1694 }
1695 if (channel->pInterfaceStat->mdm.Disc_Frame_Rej) {
1696 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1697 "MDM Disc Frame Reject = %lu", channel->pInterfaceStat->mdm.Disc_Frame_Rej);
1698 }
1699 if (channel->pInterfaceStat->mdm.Disc_V42bis) {
1700 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1701 "MDM Disc V.42bis = %lu", channel->pInterfaceStat->mdm.Disc_V42bis);
1702 }
1703 break;
1704
1705 case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE:
1706 if (channel->pInterfaceStat->fax.Disc_Normal) {
1707 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1708 "FAX Disc Normal = %lu", channel->pInterfaceStat->fax.Disc_Normal);
1709 }
1710 if (channel->pInterfaceStat->fax.Disc_Not_Ident) {
1711 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1712 "FAX Disc Not Ident. = %lu", channel->pInterfaceStat->fax.Disc_Not_Ident);
1713 }
1714 if (channel->pInterfaceStat->fax.Disc_No_Response) {
1715 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1716 "FAX Disc No Response = %lu", channel->pInterfaceStat->fax.Disc_No_Response);
1717 }
1718 if (channel->pInterfaceStat->fax.Disc_Retries) {
1719 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1720 "FAX Disc Max Retries = %lu", channel->pInterfaceStat->fax.Disc_Retries);
1721 }
1722 if (channel->pInterfaceStat->fax.Disc_Unexp_Msg) {
1723 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1724 "FAX Unexp. Msg. = %lu", channel->pInterfaceStat->fax.Disc_Unexp_Msg);
1725 }
1726 if (channel->pInterfaceStat->fax.Disc_No_Polling) {
1727 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1728 "FAX Disc No Polling = %lu", channel->pInterfaceStat->fax.Disc_No_Polling);
1729 }
1730 if (channel->pInterfaceStat->fax.Disc_Training) {
1731 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1732 "FAX Disc Training = %lu", channel->pInterfaceStat->fax.Disc_Training);
1733 }
1734 if (channel->pInterfaceStat->fax.Disc_Unexpected) {
1735 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1736 "FAX Disc Unexpected = %lu", channel->pInterfaceStat->fax.Disc_Unexpected);
1737 }
1738 if (channel->pInterfaceStat->fax.Disc_Application) {
1739 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1740 "FAX Disc Application = %lu", channel->pInterfaceStat->fax.Disc_Application);
1741 }
1742 if (channel->pInterfaceStat->fax.Disc_Incompat) {
1743 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1744 "FAX Disc Incompatible = %lu", channel->pInterfaceStat->fax.Disc_Incompat);
1745 }
1746 if (channel->pInterfaceStat->fax.Disc_No_Command) {
1747 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1748 "FAX Disc No Command = %lu", channel->pInterfaceStat->fax.Disc_No_Command);
1749 }
1750 if (channel->pInterfaceStat->fax.Disc_Long_Msg) {
1751 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1752 "FAX Disc Long Msg. = %lu", channel->pInterfaceStat->fax.Disc_Long_Msg);
1753 }
1754 if (channel->pInterfaceStat->fax.Disc_Supervisor) {
1755 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1756 "FAX Disc Supervisor = %lu", channel->pInterfaceStat->fax.Disc_Supervisor);
1757 }
1758 if (channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD) {
1759 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1760 "FAX Disc SUP SEP PWD = %lu", channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD);
1761 }
1762 if (channel->pInterfaceStat->fax.Disc_Invalid_Msg) {
1763 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1764 "FAX Disc Invalid Msg. = %lu", channel->pInterfaceStat->fax.Disc_Invalid_Msg);
1765 }
1766 if (channel->pInterfaceStat->fax.Disc_Page_Coding) {
1767 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1768 "FAX Disc Page Coding = %lu", channel->pInterfaceStat->fax.Disc_Page_Coding);
1769 }
1770 if (channel->pInterfaceStat->fax.Disc_App_Timeout) {
1771 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1772 "FAX Disc Appl. T.o. = %lu", channel->pInterfaceStat->fax.Disc_App_Timeout);
1773 }
1774 if (channel->pInterfaceStat->fax.Disc_Unspecified) {
1775 diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
1776 "FAX Disc Unspec. = %lu", channel->pInterfaceStat->fax.Disc_Unspecified);
1777 }
1778 break;
1779 }
1780}
1781
1782/*
1783 Receive trace information from the Management Interface and store it in the
1784 internal trace buffer with MSG_TYPE_MLOG as is, without any filtering.
1785 Event Filtering and formatting is done in Management Interface self.
1786*/
1787static void diva_maint_trace_notify(void *user_context,
1788 diva_strace_library_interface_t *hLib,
1789 int Adapter,
1790 void *xlog_buffer,
1791 int length) {
1792 diva_maint_client_t *pC = (diva_maint_client_t *)user_context;
1793 diva_dbg_entry_head_t *pmsg;
1794 word size;
1795 dword sec, usec;
1796 int ch = TraceFilterChannel;
1797 int id = TraceFilterIdent;
1798
1799 /*
1800 Selective trace
1801 */
1802 if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
1803 (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
1804 const char *p = NULL;
1805 int ch_value = -1;
1806 MI_XLOG_HDR *TrcData = (MI_XLOG_HDR *)xlog_buffer;
1807
1808 if (Adapter != clients[id].logical) {
1809 return; /* Ignore all trace messages from other adapters */
1810 }
1811
1812 if (TrcData->code == 24) {
1813 p = (char *)&TrcData->code;
1814 p += 2;
1815 }
1816
1817 /*
1818 All L1 messages start as [dsp,ch], so we can filter this information
1819 and filter out all messages that use different channel
1820 */
1821 if (p && p[0] == '[') {
1822 if (p[2] == ',') {
1823 p += 3;
1824 ch_value = *p - '0';
1825 } else if (p[3] == ',') {
1826 p += 4;
1827 ch_value = *p - '0';
1828 }
1829 if (ch_value >= 0) {
1830 if (p[2] == ']') {
1831 ch_value = ch_value * 10 + p[1] - '0';
1832 }
1833 if (ch_value != ch) {
1834 return; /* Ignore other channels */
1835 }
1836 }
1837 }
1838
1839 } else if (TraceFilter[0] != 0) {
1840 return; /* Ignore trace if trace filter is activated, but idle */
1841 }
1842
1843 diva_os_get_time(&sec, &usec);
1844
1845 while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
1846 (word)length + sizeof(*pmsg)))) {
1847 if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
1848 queueFreeMsg(dbg_queue);
1849 } else {
1850 break;
1851 }
1852 }
1853 if (pmsg) {
1854 memcpy(&pmsg[1], xlog_buffer, length);
1855 pmsg->sequence = dbg_sequence++;
1856 pmsg->time_sec = sec;
1857 pmsg->time_usec = usec;
1858 pmsg->facility = MSG_TYPE_MLOG;
1859 pmsg->dli = pC->logical;
1860 pmsg->drv_id = pC->hDbg->id;
1861 pmsg->di_cpu = 0;
1862 pmsg->data_length = length;
1863 queueCompleteMsg(pmsg);
1864 if (queueCount(dbg_queue)) {
1865 diva_maint_wakeup_read();
1866 }
1867 }
1868}
1869
1870
1871/*
1872 Convert MAINT trace mask to management interface trace mask/work/facility and
1873 issue command to management interface
1874*/
1875static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask) {
1876 if (pC->request && pC->hDbg && pC->pIdiLib) {
1877 dword changed = pC->hDbg->dbgMask ^ old_mask;
1878
1879 if (changed & DIVA_MGT_DBG_TRACE) {
1880 (*(pC->pIdiLib->DivaSTraceSetInfo))(pC->pIdiLib,
1881 (pC->hDbg->dbgMask & DIVA_MGT_DBG_TRACE) != 0);
1882 }
1883 if (changed & DIVA_MGT_DBG_DCHAN) {
1884 (*(pC->pIdiLib->DivaSTraceSetDChannel))(pC->pIdiLib,
1885 (pC->hDbg->dbgMask & DIVA_MGT_DBG_DCHAN) != 0);
1886 }
1887 if (!TraceFilter[0]) {
1888 if (changed & DIVA_MGT_DBG_IFC_BCHANNEL) {
1889 int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
1890
1891 for (i = 0; i < pC->channels; i++) {
1892 (*(pC->pIdiLib->DivaSTraceSetBChannel))(pC->pIdiLib, i + 1, state);
1893 }
1894 }
1895 if (changed & DIVA_MGT_DBG_IFC_AUDIO) {
1896 int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);
1897
1898 for (i = 0; i < pC->channels; i++) {
1899 (*(pC->pIdiLib->DivaSTraceSetAudioTap))(pC->pIdiLib, i + 1, state);
1900 }
1901 }
1902 }
1903 }
1904}
1905
1906
1907void diva_mnt_internal_dprintf(dword drv_id, dword type, char *fmt, ...) {
1908 va_list ap;
1909
1910 va_start(ap, fmt);
1911 DI_format(0, (word)drv_id, (int)type, fmt, ap);
1912 va_end(ap);
1913}
1914
1915/*
1916 Shutdown all adapters before driver removal
1917*/
1918int diva_mnt_shutdown_xdi_adapters(void) {
1919 diva_os_spin_lock_magic_t old_irql, old_irql1;
1920 int i, fret = 0;
1921 byte *pmem;
1922
1923
1924 for (i = 1; i < ARRAY_SIZE(clients); i++) {
1925 pmem = NULL;
1926
1927 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "unload");
1928 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "unload");
1929
1930 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
1931 if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].pIdiLib) == 1) {
1932 /*
1933 Adapter removal complete
1934 */
1935 if (clients[i].pIdiLib) {
1936 (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
1937 clients[i].pIdiLib = NULL;
1938
1939 pmem = clients[i].pmem;
1940 clients[i].pmem = NULL;
1941 }
1942 clients[i].hDbg = NULL;
1943 clients[i].request_pending = 0;
1944
1945 if (clients[i].dma_handle >= 0) {
1946 /*
1947 Free DMA handle
1948 */
1949 diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
1950 clients[i].dma_handle = -1;
1951 }
1952 clients[i].request = NULL;
1953 } else {
1954 fret = -1;
1955 }
1956 }
1957
1958 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "unload");
1959 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
1960 clients[i].request_pending = 0;
1961 (*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
1962 if (clients[i].dma_handle >= 0) {
1963 diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
1964 clients[i].dma_handle = -1;
1965 }
1966 }
1967 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "unload");
1968
1969 if (pmem) {
1970 diva_os_free(0, pmem);
1971 }
1972 }
1973
1974 return (fret);
1975}
1976
1977/*
1978 Set/Read the trace filter used for selective tracing.
1979 Affects B- and Audio Tap trace mask at run time
1980*/
1981int diva_set_trace_filter(int filter_length, const char *filter) {
1982 diva_os_spin_lock_magic_t old_irql, old_irql1;
1983 int i, ch, on, client_b_on, client_atap_on;
1984
1985 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
1986 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
1987
1988 if (filter_length <= DIVA_MAX_SELECTIVE_FILTER_LENGTH) {
1989 memcpy(&TraceFilter[0], filter, filter_length);
1990 if (TraceFilter[filter_length]) {
1991 TraceFilter[filter_length] = 0;
1992 }
1993 if (TraceFilter[0] == '*') {
1994 TraceFilter[0] = 0;
1995 }
1996 } else {
1997 filter_length = -1;
1998 }
1999
2000 TraceFilterIdent = -1;
2001 TraceFilterChannel = -1;
2002
2003 on = (TraceFilter[0] == 0);
2004
2005 for (i = 1; i < ARRAY_SIZE(clients); i++) {
2006 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
2007 client_b_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
2008 client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);
2009 for (ch = 0; ch < clients[i].channels; ch++) {
2010 (*(clients[i].pIdiLib->DivaSTraceSetBChannel))(clients[i].pIdiLib->hLib, ch + 1, client_b_on);
2011 (*(clients[i].pIdiLib->DivaSTraceSetAudioTap))(clients[i].pIdiLib->hLib, ch + 1, client_atap_on);
2012 }
2013 }
2014 }
2015
2016 for (i = 1; i < ARRAY_SIZE(clients); i++) {
2017 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
2018 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
2019 clients[i].request_pending = 0;
2020 (*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
2021 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
2022 }
2023 }
2024
2025 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
2026 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
2027
2028 return (filter_length);
2029}
2030
2031int diva_get_trace_filter(int max_length, char *filter) {
2032 diva_os_spin_lock_magic_t old_irql;
2033 int len;
2034
2035 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read_filter");
2036 len = strlen(&TraceFilter[0]) + 1;
2037 if (max_length >= len) {
2038 memcpy(filter, &TraceFilter[0], len);
2039 }
2040 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_filter");
2041
2042 return (len);
2043}
2044
2045static int diva_dbg_cmp_key(const char *ref, const char *key) {
2046 while (*key && (*ref++ == *key++));
2047 return (!*key && !*ref);
2048}
2049
2050/*
2051 In case trace filter starts with "C" character then
2052 all following characters are interpreted as command.
2053 Following commands are available:
2054 - single, trace single call at time, independent from CPN/CiPN
2055*/
2056static int diva_mnt_cmp_nmbr(const char *nmbr) {
2057 const char *ref = &TraceFilter[0];
2058 int ref_len = strlen(&TraceFilter[0]), nmbr_len = strlen(nmbr);
2059
2060 if (ref[0] == 'C') {
2061 if (diva_dbg_cmp_key(&ref[1], "single")) {
2062 return (0);
2063 }
2064 return (-1);
2065 }
2066
2067 if (!ref_len || (ref_len > nmbr_len)) {
2068 return (-1);
2069 }
2070
2071 nmbr = nmbr + nmbr_len - 1;
2072 ref = ref + ref_len - 1;
2073
2074 while (ref_len--) {
2075 if (*nmbr-- != *ref--) {
2076 return (-1);
2077 }
2078 }
2079
2080 return (0);
2081}
2082
2083static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic) {
2084 ENTITY e;
2085 IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
2086
2087 if (!request) {
2088 return (-1);
2089 }
2090
2091 pReq->xdi_dma_descriptor_operation.Req = 0;
2092 pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
2093
2094 pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
2095 pReq->xdi_dma_descriptor_operation.info.descriptor_number = -1;
2096 pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
2097 pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0;
2098
2099 (*request)((ENTITY *)pReq);
2100
2101 if (!pReq->xdi_dma_descriptor_operation.info.operation &&
2102 (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
2103 pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
2104 *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
2105 return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
2106 } else {
2107 return (-1);
2108 }
2109}
2110
2111static void diva_free_dma_descriptor(IDI_CALL request, int nr) {
2112 ENTITY e;
2113 IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
2114
2115 if (!request || (nr < 0)) {
2116 return;
2117 }
2118
2119 pReq->xdi_dma_descriptor_operation.Req = 0;
2120 pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
2121
2122 pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
2123 pReq->xdi_dma_descriptor_operation.info.descriptor_number = nr;
2124 pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
2125 pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0;
2126
2127 (*request)((ENTITY *)pReq);
2128}
diff --git a/drivers/isdn/hardware/eicon/debug_if.h b/drivers/isdn/hardware/eicon/debug_if.h
deleted file mode 100644
index fc5953a35ff6..000000000000
--- a/drivers/isdn/hardware/eicon/debug_if.h
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Technology Corporation, 2000.
4 *
5 This source file is supplied for the use with Eicon
6 Technology Corporation's range of DIVA Server Adapters.
7 *
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12 *
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
15 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 See the GNU General Public License for more details.
17 *
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23#ifndef __DIVA_DEBUG_IF_H__
24#define __DIVA_DEBUG_IF_H__
25#define MSG_TYPE_DRV_ID 0x0001
26#define MSG_TYPE_FLAGS 0x0002
27#define MSG_TYPE_STRING 0x0003
28#define MSG_TYPE_BINARY 0x0004
29#define MSG_TYPE_MLOG 0x0005
30
31#define MSG_FRAME_MAX_SIZE 2150
32
33typedef struct _diva_dbg_entry_head {
34 dword sequence;
35 dword time_sec;
36 dword time_usec;
37 dword facility;
38 dword dli;
39 dword drv_id;
40 dword di_cpu;
41 dword data_length;
42} diva_dbg_entry_head_t;
43
44int diva_maint_init(byte *base, unsigned long length, int do_init);
45void *diva_maint_finit(void);
46dword diva_dbg_q_length(void);
47diva_dbg_entry_head_t *diva_maint_get_message(word *size,
48 diva_os_spin_lock_magic_t *old_irql);
49void diva_maint_ack_message(int do_release,
50 diva_os_spin_lock_magic_t *old_irql);
51void diva_maint_prtComp(char *format, ...);
52void diva_maint_wakeup_read(void);
53int diva_get_driver_info(dword id, byte *data, int data_length);
54int diva_get_driver_dbg_mask(dword id, byte *data);
55int diva_set_driver_dbg_mask(dword id, dword mask);
56void diva_mnt_remove_xdi_adapter(const DESCRIPTOR *d);
57void diva_mnt_add_xdi_adapter(const DESCRIPTOR *d);
58int diva_mnt_shutdown_xdi_adapters(void);
59
60#define DIVA_MAX_SELECTIVE_FILTER_LENGTH 127
61int diva_set_trace_filter(int filter_length, const char *filter);
62int diva_get_trace_filter(int max_length, char *filter);
63
64
65#define DITRACE_CMD_GET_DRIVER_INFO 1
66#define DITRACE_READ_DRIVER_DBG_MASK 2
67#define DITRACE_WRITE_DRIVER_DBG_MASK 3
68#define DITRACE_READ_TRACE_ENTRY 4
69#define DITRACE_READ_TRACE_ENTRYS 5
70#define DITRACE_WRITE_SELECTIVE_TRACE_FILTER 6
71#define DITRACE_READ_SELECTIVE_TRACE_FILTER 7
72
73/*
74 Trace lavels for debug via management interface
75*/
76#define DIVA_MGT_DBG_TRACE 0x00000001 /* All trace messages from the card */
77#define DIVA_MGT_DBG_DCHAN 0x00000002 /* All D-channel relater trace messages */
78#define DIVA_MGT_DBG_MDM_PROGRESS 0x00000004 /* Modem progress events */
79#define DIVA_MGT_DBG_FAX_PROGRESS 0x00000008 /* Fax progress events */
80#define DIVA_MGT_DBG_IFC_STATISTICS 0x00000010 /* Interface call statistics */
81#define DIVA_MGT_DBG_MDM_STATISTICS 0x00000020 /* Global modem statistics */
82#define DIVA_MGT_DBG_FAX_STATISTICS 0x00000040 /* Global call statistics */
83#define DIVA_MGT_DBG_LINE_EVENTS 0x00000080 /* Line state events */
84#define DIVA_MGT_DBG_IFC_EVENTS 0x00000100 /* Interface/L1/L2 state events */
85#define DIVA_MGT_DBG_IFC_BCHANNEL 0x00000200 /* B-Channel trace for all channels */
86#define DIVA_MGT_DBG_IFC_AUDIO 0x00000400 /* Audio Tap trace for all channels */
87
88# endif /* DEBUG_IF___H */
diff --git a/drivers/isdn/hardware/eicon/debuglib.c b/drivers/isdn/hardware/eicon/debuglib.c
deleted file mode 100644
index d5b1092a54f0..000000000000
--- a/drivers/isdn/hardware/eicon/debuglib.c
+++ /dev/null
@@ -1,156 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26
27#include "debuglib.h"
28
29#ifdef DIVA_NO_DEBUGLIB
30static DIVA_DI_PRINTF dprintf;
31#else /* DIVA_NO_DEBUGLIB */
32
33_DbgHandle_ myDriverDebugHandle = { 0 /*!Registered*/, DBG_HANDLE_VERSION };
34DIVA_DI_PRINTF dprintf = no_printf;
35/*****************************************************************************/
36#define DBG_FUNC(name) \
37 void \
38 myDbgPrint_##name(char *format, ...) \
39 { va_list ap; \
40 if (myDriverDebugHandle.dbg_prt) \
41 { va_start(ap, format); \
42 (myDriverDebugHandle.dbg_prt) \
43 (myDriverDebugHandle.id, DLI_##name, format, ap); \
44 va_end(ap); \
45 } }
46DBG_FUNC(LOG)
47DBG_FUNC(FTL)
48DBG_FUNC(ERR)
49DBG_FUNC(TRC)
50DBG_FUNC(MXLOG)
51DBG_FUNC(FTL_MXLOG)
52void
53myDbgPrint_EVL(long msgID, ...)
54{ va_list ap;
55 if (myDriverDebugHandle.dbg_ev)
56 { va_start(ap, msgID);
57 (myDriverDebugHandle.dbg_ev)
58 (myDriverDebugHandle.id, (unsigned long)msgID, ap);
59 va_end(ap);
60 } }
61DBG_FUNC(REG)
62DBG_FUNC(MEM)
63DBG_FUNC(SPL)
64DBG_FUNC(IRP)
65DBG_FUNC(TIM)
66DBG_FUNC(BLK)
67DBG_FUNC(TAPI)
68DBG_FUNC(NDIS)
69DBG_FUNC(CONN)
70DBG_FUNC(STAT)
71DBG_FUNC(SEND)
72DBG_FUNC(RECV)
73DBG_FUNC(PRV0)
74DBG_FUNC(PRV1)
75DBG_FUNC(PRV2)
76DBG_FUNC(PRV3)
77/*****************************************************************************/
78int
79DbgRegister(char *drvName, char *drvTag, unsigned long dbgMask)
80{
81 int len;
82/*
83 * deregister (if already registered) and zero out myDriverDebugHandle
84 */
85 DbgDeregister();
86/*
87 * initialize the debug handle
88 */
89 myDriverDebugHandle.Version = DBG_HANDLE_VERSION;
90 myDriverDebugHandle.id = -1;
91 myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG);
92 len = strlen(drvName);
93 memcpy(myDriverDebugHandle.drvName, drvName,
94 (len < sizeof(myDriverDebugHandle.drvName)) ?
95 len : sizeof(myDriverDebugHandle.drvName) - 1);
96 len = strlen(drvTag);
97 memcpy(myDriverDebugHandle.drvTag, drvTag,
98 (len < sizeof(myDriverDebugHandle.drvTag)) ?
99 len : sizeof(myDriverDebugHandle.drvTag) - 1);
100/*
101 * Try to register debugging via old (and only) interface
102 */
103 dprintf("\000\377", &myDriverDebugHandle);
104 if (myDriverDebugHandle.dbg_prt)
105 {
106 return (1);
107 }
108/*
109 * Check if we registered with an old maint driver (see debuglib.h)
110 */
111 if (myDriverDebugHandle.dbg_end != NULL
112 /* location of 'dbg_prt' in _OldDbgHandle_ struct */
113 && (myDriverDebugHandle.regTime.LowPart ||
114 myDriverDebugHandle.regTime.HighPart))
115 /* same location as in _OldDbgHandle_ struct */
116 {
117 dprintf("%s: Cannot log to old maint driver !", drvName);
118 myDriverDebugHandle.dbg_end =
119 ((_OldDbgHandle_ *)&myDriverDebugHandle)->dbg_end;
120 DbgDeregister();
121 }
122 return (0);
123}
124/*****************************************************************************/
125void
126DbgSetLevel(unsigned long dbgMask)
127{
128 myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG);
129}
130/*****************************************************************************/
131void
132DbgDeregister(void)
133{
134 if (myDriverDebugHandle.dbg_end)
135 {
136 (myDriverDebugHandle.dbg_end)(&myDriverDebugHandle);
137 }
138 memset(&myDriverDebugHandle, 0, sizeof(myDriverDebugHandle));
139}
140void xdi_dbg_xlog(char *x, ...) {
141 va_list ap;
142 va_start(ap, x);
143 if (myDriverDebugHandle.dbg_end &&
144 (myDriverDebugHandle.dbg_irq || myDriverDebugHandle.dbg_old) &&
145 (myDriverDebugHandle.dbgMask & DL_STAT)) {
146 if (myDriverDebugHandle.dbg_irq) {
147 (*(myDriverDebugHandle.dbg_irq))(myDriverDebugHandle.id,
148 (x[0] != 0) ? DLI_TRC : DLI_XLOG, x, ap);
149 } else {
150 (*(myDriverDebugHandle.dbg_old))(myDriverDebugHandle.id, x, ap);
151 }
152 }
153 va_end(ap);
154}
155/*****************************************************************************/
156#endif /* DIVA_NO_DEBUGLIB */
diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h
deleted file mode 100644
index 6dcbf6afb8f9..000000000000
--- a/drivers/isdn/hardware/eicon/debuglib.h
+++ /dev/null
@@ -1,322 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#if !defined(__DEBUGLIB_H__)
27#define __DEBUGLIB_H__
28#include <stdarg.h>
29/*
30 * define global debug priorities
31 */
32#define DL_LOG 0x00000001 /* always worth mentioning */
33#define DL_FTL 0x00000002 /* always sampled error */
34#define DL_ERR 0x00000004 /* any kind of error */
35#define DL_TRC 0x00000008 /* verbose information */
36#define DL_XLOG 0x00000010 /* old xlog info */
37#define DL_MXLOG 0x00000020 /* maestra xlog info */
38#define DL_FTL_MXLOG 0x00000021 /* fatal maestra xlog info */
39#define DL_EVL 0x00000080 /* special NT eventlog msg */
40#define DL_COMPAT (DL_MXLOG | DL_XLOG)
41#define DL_PRIOR_MASK (DL_EVL | DL_COMPAT | DL_TRC | DL_ERR | DL_FTL | DL_LOG)
42#define DLI_LOG 0x0100
43#define DLI_FTL 0x0200
44#define DLI_ERR 0x0300
45#define DLI_TRC 0x0400
46#define DLI_XLOG 0x0500
47#define DLI_MXLOG 0x0600
48#define DLI_FTL_MXLOG 0x0600
49#define DLI_EVL 0x0800
50/*
51 * define OS (operating system interface) debuglevel
52 */
53#define DL_REG 0x00000100 /* init/query registry */
54#define DL_MEM 0x00000200 /* memory management */
55#define DL_SPL 0x00000400 /* event/spinlock handling */
56#define DL_IRP 0x00000800 /* I/O request handling */
57#define DL_TIM 0x00001000 /* timer/watchdog handling */
58#define DL_BLK 0x00002000 /* raw data block contents */
59#define DL_OS_MASK (DL_BLK | DL_TIM | DL_IRP | DL_SPL | DL_MEM | DL_REG)
60#define DLI_REG 0x0900
61#define DLI_MEM 0x0A00
62#define DLI_SPL 0x0B00
63#define DLI_IRP 0x0C00
64#define DLI_TIM 0x0D00
65#define DLI_BLK 0x0E00
66/*
67 * define ISDN (connection interface) debuglevel
68 */
69#define DL_TAPI 0x00010000 /* debug TAPI interface */
70#define DL_NDIS 0x00020000 /* debug NDIS interface */
71#define DL_CONN 0x00040000 /* connection handling */
72#define DL_STAT 0x00080000 /* trace state machines */
73#define DL_SEND 0x00100000 /* trace raw xmitted data */
74#define DL_RECV 0x00200000 /* trace raw received data */
75#define DL_DATA (DL_SEND | DL_RECV)
76#define DL_ISDN_MASK (DL_DATA | DL_STAT | DL_CONN | DL_NDIS | DL_TAPI)
77#define DLI_TAPI 0x1100
78#define DLI_NDIS 0x1200
79#define DLI_CONN 0x1300
80#define DLI_STAT 0x1400
81#define DLI_SEND 0x1500
82#define DLI_RECV 0x1600
83/*
84 * define some private (unspecified) debuglevel
85 */
86#define DL_PRV0 0x01000000
87#define DL_PRV1 0x02000000
88#define DL_PRV2 0x04000000
89#define DL_PRV3 0x08000000
90#define DL_PRIV_MASK (DL_PRV0 | DL_PRV1 | DL_PRV2 | DL_PRV3)
91#define DLI_PRV0 0x1900
92#define DLI_PRV1 0x1A00
93#define DLI_PRV2 0x1B00
94#define DLI_PRV3 0x1C00
95#define DT_INDEX(x) ((x) & 0x000F)
96#define DL_INDEX(x) ((((x) >> 8) & 0x00FF) - 1)
97#define DLI_NAME(x) ((x) & 0xFF00)
98/*
99 * Debug mask for kernel mode tracing, if set the output is also sent to
100 * the system debug function. Requires that the project is compiled
101 * with _KERNEL_DBG_PRINT_
102 */
103#define DL_TO_KERNEL 0x40000000
104
105#ifdef DIVA_NO_DEBUGLIB
106#define myDbgPrint_LOG(x...) do { } while (0);
107#define myDbgPrint_FTL(x...) do { } while (0);
108#define myDbgPrint_ERR(x...) do { } while (0);
109#define myDbgPrint_TRC(x...) do { } while (0);
110#define myDbgPrint_MXLOG(x...) do { } while (0);
111#define myDbgPrint_EVL(x...) do { } while (0);
112#define myDbgPrint_REG(x...) do { } while (0);
113#define myDbgPrint_MEM(x...) do { } while (0);
114#define myDbgPrint_SPL(x...) do { } while (0);
115#define myDbgPrint_IRP(x...) do { } while (0);
116#define myDbgPrint_TIM(x...) do { } while (0);
117#define myDbgPrint_BLK(x...) do { } while (0);
118#define myDbgPrint_TAPI(x...) do { } while (0);
119#define myDbgPrint_NDIS(x...) do { } while (0);
120#define myDbgPrint_CONN(x...) do { } while (0);
121#define myDbgPrint_STAT(x...) do { } while (0);
122#define myDbgPrint_SEND(x...) do { } while (0);
123#define myDbgPrint_RECV(x...) do { } while (0);
124#define myDbgPrint_PRV0(x...) do { } while (0);
125#define myDbgPrint_PRV1(x...) do { } while (0);
126#define myDbgPrint_PRV2(x...) do { } while (0);
127#define myDbgPrint_PRV3(x...) do { } while (0);
128#define DBG_TEST(func, args) do { } while (0);
129#define DBG_EVL_ID(args) do { } while (0);
130
131#else /* DIVA_NO_DEBUGLIB */
132/*
133 * define low level macros for formatted & raw debugging
134 */
135#define DBG_DECL(func) extern void myDbgPrint_##func(char *, ...);
136DBG_DECL(LOG)
137DBG_DECL(FTL)
138DBG_DECL(ERR)
139DBG_DECL(TRC)
140DBG_DECL(MXLOG)
141DBG_DECL(FTL_MXLOG)
142extern void myDbgPrint_EVL(long, ...);
143DBG_DECL(REG)
144DBG_DECL(MEM)
145DBG_DECL(SPL)
146DBG_DECL(IRP)
147DBG_DECL(TIM)
148DBG_DECL(BLK)
149DBG_DECL(TAPI)
150DBG_DECL(NDIS)
151DBG_DECL(CONN)
152DBG_DECL(STAT)
153DBG_DECL(SEND)
154DBG_DECL(RECV)
155DBG_DECL(PRV0)
156DBG_DECL(PRV1)
157DBG_DECL(PRV2)
158DBG_DECL(PRV3)
159#ifdef _KERNEL_DBG_PRINT_
160/*
161 * tracing to maint and kernel if selected in the trace mask.
162 */
163#define DBG_TEST(func, args) \
164 { if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func) \
165 { \
166 if ((myDriverDebugHandle.dbgMask) & DL_TO_KERNEL) \
167 { DbgPrint args; DbgPrint("\r\n"); } \
168 myDbgPrint_##func args; \
169 } }
170#else
171/*
172 * Standard tracing to maint driver.
173 */
174#define DBG_TEST(func, args) \
175 { if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func) \
176 { myDbgPrint_##func args; \
177 } }
178#endif
179/*
180 * For event level debug use a separate define, the parameter are
181 * different and cause compiler errors on some systems.
182 */
183#define DBG_EVL_ID(args) \
184 { if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL) \
185 { myDbgPrint_EVL args; \
186 } }
187
188#endif /* DIVA_NO_DEBUGLIB */
189
190#define DBG_LOG(args) DBG_TEST(LOG, args)
191#define DBG_FTL(args) DBG_TEST(FTL, args)
192#define DBG_ERR(args) DBG_TEST(ERR, args)
193#define DBG_TRC(args) DBG_TEST(TRC, args)
194#define DBG_MXLOG(args) DBG_TEST(MXLOG, args)
195#define DBG_FTL_MXLOG(args) DBG_TEST(FTL_MXLOG, args)
196#define DBG_EVL(args) DBG_EVL_ID(args)
197#define DBG_REG(args) DBG_TEST(REG, args)
198#define DBG_MEM(args) DBG_TEST(MEM, args)
199#define DBG_SPL(args) DBG_TEST(SPL, args)
200#define DBG_IRP(args) DBG_TEST(IRP, args)
201#define DBG_TIM(args) DBG_TEST(TIM, args)
202#define DBG_BLK(args) DBG_TEST(BLK, args)
203#define DBG_TAPI(args) DBG_TEST(TAPI, args)
204#define DBG_NDIS(args) DBG_TEST(NDIS, args)
205#define DBG_CONN(args) DBG_TEST(CONN, args)
206#define DBG_STAT(args) DBG_TEST(STAT, args)
207#define DBG_SEND(args) DBG_TEST(SEND, args)
208#define DBG_RECV(args) DBG_TEST(RECV, args)
209#define DBG_PRV0(args) DBG_TEST(PRV0, args)
210#define DBG_PRV1(args) DBG_TEST(PRV1, args)
211#define DBG_PRV2(args) DBG_TEST(PRV2, args)
212#define DBG_PRV3(args) DBG_TEST(PRV3, args)
213/*
214 * prototypes for debug register/deregister functions in "debuglib.c"
215 */
216#ifdef DIVA_NO_DEBUGLIB
217#define DbgRegister(name, tag, mask) do { } while (0)
218#define DbgDeregister() do { } while (0)
219#define DbgSetLevel(mask) do { } while (0)
220#else
221extern DIVA_DI_PRINTF dprintf;
222extern int DbgRegister(char *drvName, char *drvTag, unsigned long dbgMask);
223extern void DbgDeregister(void);
224extern void DbgSetLevel(unsigned long dbgMask);
225#endif
226/*
227 * driver internal structure for debug handling;
228 * in client drivers this structure is maintained in "debuglib.c",
229 * in the debug driver "debug.c" maintains a chain of such structs.
230 */
231typedef struct _DbgHandle_ *pDbgHandle;
232typedef void (*DbgEnd)(pDbgHandle);
233typedef void (*DbgLog)(unsigned short, int, char *, va_list);
234typedef void (*DbgOld)(unsigned short, char *, va_list);
235typedef void (*DbgEv)(unsigned short, unsigned long, va_list);
236typedef void (*DbgIrq)(unsigned short, int, char *, va_list);
237typedef struct _DbgHandle_
238{ char Registered; /* driver successfully registered */
239#define DBG_HANDLE_REG_NEW 0x01 /* this (new) structure */
240#define DBG_HANDLE_REG_OLD 0x7f /* old structure (see below) */
241 char Version; /* version of this structure */
242#define DBG_HANDLE_VERSION 1 /* contains dbg_old function now */
243#define DBG_HANDLE_VER_EXT 2 /* pReserved points to extended info*/
244 short id; /* internal id of registered driver */
245 struct _DbgHandle_ *next; /* ptr to next registered driver */
246 struct /*LARGE_INTEGER*/ {
247 unsigned long LowPart;
248 long HighPart;
249 } regTime; /* timestamp for registration */
250 void *pIrp; /* ptr to pending i/o request */
251 unsigned long dbgMask; /* current debug mask */
252 char drvName[128]; /* ASCII name of registered driver */
253 char drvTag[64]; /* revision string */
254 DbgEnd dbg_end; /* function for debug closing */
255 DbgLog dbg_prt; /* function for debug appending */
256 DbgOld dbg_old; /* function for old debug appending */
257 DbgEv dbg_ev; /* function for Windows NT Eventlog */
258 DbgIrq dbg_irq; /* function for irql checked debug */
259 void *pReserved3;
260} _DbgHandle_;
261extern _DbgHandle_ myDriverDebugHandle;
262typedef struct _OldDbgHandle_
263{ struct _OldDbgHandle_ *next;
264 void *pIrp;
265 long regTime[2];
266 unsigned long dbgMask;
267 short id;
268 char drvName[78];
269 DbgEnd dbg_end;
270 DbgLog dbg_prt;
271} _OldDbgHandle_;
272/* the differences in DbgHandles
273 old: tmp: new:
274 0 long next char Registered char Registered
275 char filler char Version
276 short id short id
277 4 long pIrp long regTime.lo long next
278 8 long regTime.lo long regTime.hi long regTime.lo
279 12 long regTime.hi long next long regTime.hi
280 16 long dbgMask long pIrp long pIrp
281 20 short id long dbgMask long dbgMask
282 22 char drvName[78] ..
283 24 .. char drvName[16] char drvName[16]
284 40 .. char drvTag[64] char drvTag[64]
285 100 void *dbg_end .. ..
286 104 void *dbg_prt void *dbg_end void *dbg_end
287 108 .. void *dbg_prt void *dbg_prt
288 112 .. .. void *dbg_old
289 116 .. .. void *dbg_ev
290 120 .. .. void *dbg_irq
291 124 .. .. void *pReserved3
292 ( new->id == 0 && *((short *)&new->dbgMask) == -1 ) identifies "old",
293 new->Registered and new->Version overlay old->next,
294 new->next overlays old->pIrp, new->regTime matches old->regTime and
295 thus these fields can be maintained in new struct whithout trouble;
296 id, dbgMask, drvName, dbg_end and dbg_prt need special handling !
297*/
298#define DBG_EXT_TYPE_CARD_TRACE 0x00000001
299typedef struct
300{
301 unsigned long ExtendedType;
302 union
303 {
304 /* DBG_EXT_TYPE_CARD_TRACE */
305 struct
306 {
307 void (*MaskChangedNotify)(void *pContext);
308 unsigned long ModuleTxtMask;
309 unsigned long DebugLevel;
310 unsigned long B_ChannelMask;
311 unsigned long LogBufferSize;
312 } CardTrace;
313 } Data;
314} _DbgExtendedInfo_;
315#ifndef DIVA_NO_DEBUGLIB
316/* -------------------------------------------------------------
317 Function used for xlog-style debug
318 ------------------------------------------------------------- */
319#define XDI_USE_XLOG 1
320void xdi_dbg_xlog(char *x, ...);
321#endif /* DIVA_NO_DEBUGLIB */
322#endif /* __DEBUGLIB_H__ */
diff --git a/drivers/isdn/hardware/eicon/dfifo.h b/drivers/isdn/hardware/eicon/dfifo.h
deleted file mode 100644
index 6a1d3337f99e..000000000000
--- a/drivers/isdn/hardware/eicon/dfifo.h
+++ /dev/null
@@ -1,54 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_IDI_DFIFO_INC__
27#define __DIVA_IDI_DFIFO_INC__
28#define DIVA_DFIFO_CACHE_SZ 64 /* Used to isolate pipe from
29 rest of the world
30 should be divisible by 4
31 */
32#define DIVA_DFIFO_RAW_SZ (2512 * 8)
33#define DIVA_DFIFO_DATA_SZ 68
34#define DIVA_DFIFO_HDR_SZ 4
35#define DIVA_DFIFO_SEGMENT_SZ (DIVA_DFIFO_DATA_SZ + DIVA_DFIFO_HDR_SZ)
36#define DIVA_DFIFO_SEGMENTS ((DIVA_DFIFO_RAW_SZ) / (DIVA_DFIFO_SEGMENT_SZ) + 1)
37#define DIVA_DFIFO_MEM_SZ ( \
38 (DIVA_DFIFO_SEGMENT_SZ) * (DIVA_DFIFO_SEGMENTS) + \
39 (DIVA_DFIFO_CACHE_SZ) * 2 \
40 )
41#define DIVA_DFIFO_STEP DIVA_DFIFO_SEGMENT_SZ
42/* -------------------------------------------------------------------------
43 Block header layout is:
44 byte[0] -> flags
45 byte[1] -> length of data in block
46 byte[2] -> reserved
47 byte[4] -> reserved
48 ------------------------------------------------------------------------- */
49#define DIVA_DFIFO_WRAP 0x80 /* This is the last block in fifo */
50#define DIVA_DFIFO_READY 0x40 /* This block is ready for processing */
51#define DIVA_DFIFO_LAST 0x20 /* This block is last in message */
52#define DIVA_DFIFO_AUTO 0x10 /* Don't look for 'ready', don't ack */
53int diva_dfifo_create(void *start, int length);
54#endif
diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
deleted file mode 100644
index cd3fba1add12..000000000000
--- a/drivers/isdn/hardware/eicon/di.c
+++ /dev/null
@@ -1,835 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include "platform.h"
27#include "pc.h"
28#include "pr_pc.h"
29#include "di_defs.h"
30#include "di.h"
31#if !defined USE_EXTENDED_DEBUGS
32#include "dimaint.h"
33#else
34#define dprintf
35#endif
36#include "io.h"
37#include "dfifo.h"
38#define PR_RAM ((struct pr_ram *)0)
39#define RAM ((struct dual *)0)
40/*------------------------------------------------------------------*/
41/* local function prototypes */
42/*------------------------------------------------------------------*/
43void pr_out(ADAPTER *a);
44byte pr_dpc(ADAPTER *a);
45static byte pr_ready(ADAPTER *a);
46static byte isdn_rc(ADAPTER *, byte, byte, byte, word, dword, dword);
47static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word);
48/* -----------------------------------------------------------------
49 Functions used for the extended XDI Debug
50 macros
51 global convergence counter (used by all adapters)
52 Look by the implementation part of the functions
53 about the parameters.
54 If you change the dubugging parameters, then you should update
55 the aididbg.doc in the IDI doc's.
56 ----------------------------------------------------------------- */
57#if defined(XDI_USE_XLOG)
58#define XDI_A_NR(_x_) ((byte)(((ISDN_ADAPTER *)(_x_->io))->ANum))
59static void xdi_xlog(byte *msg, word code, int length);
60static byte xdi_xlog_sec = 0;
61#else
62#define XDI_A_NR(_x_) ((byte)0)
63#endif
64static void xdi_xlog_rc_event(byte Adapter,
65 byte Id, byte Ch, byte Rc, byte cb, byte type);
66static void xdi_xlog_request(byte Adapter, byte Id,
67 byte Ch, byte Req, byte type);
68static void xdi_xlog_ind(byte Adapter,
69 byte Id,
70 byte Ch,
71 byte Ind,
72 byte rnr_valid,
73 byte rnr,
74 byte type);
75/*------------------------------------------------------------------*/
76/* output function */
77/*------------------------------------------------------------------*/
78void pr_out(ADAPTER *a)
79{
80 byte e_no;
81 ENTITY *this = NULL;
82 BUFFERS *X;
83 word length;
84 word i;
85 word clength;
86 REQ *ReqOut;
87 byte more;
88 byte ReadyCount;
89 byte ReqCount;
90 byte Id;
91 dtrc(dprintf("pr_out"));
92 /* while a request is pending ... */
93 e_no = look_req(a);
94 if (!e_no)
95 {
96 dtrc(dprintf("no_req"));
97 return;
98 }
99 ReadyCount = pr_ready(a);
100 if (!ReadyCount)
101 {
102 dtrc(dprintf("not_ready"));
103 return;
104 }
105 ReqCount = 0;
106 while (e_no && ReadyCount) {
107 next_req(a);
108 this = entity_ptr(a, e_no);
109#ifdef USE_EXTENDED_DEBUGS
110 if (!this)
111 {
112 DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
113 xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
114 e_no = look_req(a);
115 ReadyCount--;
116 continue;
117 }
118 {
119 DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
120 }
121#else
122 dbug(dprintf("out:Req=%x,Id=%x,Ch=%x", this->Req, this->Id, this->ReqCh));
123#endif
124 /* get address of next available request buffer */
125 ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)];
126#if defined(DIVA_ISTREAM)
127 if (!(a->tx_stream[this->Id] &&
128 this->Req == N_DATA)) {
129#endif
130 /* now copy the data from the current data buffer into the */
131 /* adapters request buffer */
132 length = 0;
133 i = this->XCurrent;
134 X = PTR_X(a, this);
135 while (i < this->XNum && length < 270) {
136 clength = min((word)(270 - length), (word)(X[i].PLength-this->XOffset));
137 a->ram_out_buffer(a,
138 &ReqOut->XBuffer.P[length],
139 PTR_P(a, this, &X[i].P[this->XOffset]),
140 clength);
141 length += clength;
142 this->XOffset += clength;
143 if (this->XOffset == X[i].PLength) {
144 this->XCurrent = (byte)++i;
145 this->XOffset = 0;
146 }
147 }
148#if defined(DIVA_ISTREAM)
149 } else { /* Use CMA extension in order to transfer data to the card */
150 i = this->XCurrent;
151 X = PTR_X(a, this);
152 while (i < this->XNum) {
153 diva_istream_write(a,
154 this->Id,
155 PTR_P(a, this, &X[i].P[0]),
156 X[i].PLength,
157 ((i + 1) == this->XNum),
158 0, 0);
159 this->XCurrent = (byte)++i;
160 }
161 length = 0;
162 }
163#endif
164 a->ram_outw(a, &ReqOut->XBuffer.length, length);
165 a->ram_out(a, &ReqOut->ReqId, this->Id);
166 a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
167 /* if it's a specific request (no ASSIGN) ... */
168 if (this->Id & 0x1f) {
169 /* if buffers are left in the list of data buffers do */
170 /* do chaining (LL_MDATA, N_MDATA) */
171 this->More++;
172 if (i < this->XNum && this->MInd) {
173 xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->MInd,
174 a->IdTypeTable[this->No]);
175 a->ram_out(a, &ReqOut->Req, this->MInd);
176 more = true;
177 }
178 else {
179 xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req,
180 a->IdTypeTable[this->No]);
181 this->More |= XMOREF;
182 a->ram_out(a, &ReqOut->Req, this->Req);
183 more = false;
184 if (a->FlowControlIdTable[this->ReqCh] == this->Id)
185 a->FlowControlSkipTable[this->ReqCh] = true;
186 /*
187 Note that remove request was sent to the card
188 */
189 if (this->Req == REMOVE) {
190 a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING;
191 }
192 }
193 /* if we did chaining, this entity is put back into the */
194 /* request queue */
195 if (more) {
196 req_queue(a, this->No);
197 }
198 }
199 /* else it's a ASSIGN */
200 else {
201 /* save the request code used for buffer chaining */
202 this->MInd = 0;
203 if (this->Id == BLLC_ID) this->MInd = LL_MDATA;
204 if (this->Id == NL_ID ||
205 this->Id == TASK_ID ||
206 this->Id == MAN_ID
207 ) this->MInd = N_MDATA;
208 /* send the ASSIGN */
209 a->IdTypeTable[this->No] = this->Id;
210 xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req, this->Id);
211 this->More |= XMOREF;
212 a->ram_out(a, &ReqOut->Req, this->Req);
213 /* save the reference of the ASSIGN */
214 assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference));
215 }
216 a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next));
217 ReadyCount--;
218 ReqCount++;
219 e_no = look_req(a);
220 }
221 /* send the filled request buffers to the ISDN adapter */
222 a->ram_out(a, &PR_RAM->ReqInput,
223 (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount));
224 /* if it is a 'unreturncoded' UREMOVE request, remove the */
225 /* Id from our table after sending the request */
226 if (this && (this->Req == UREMOVE) && this->Id) {
227 Id = this->Id;
228 e_no = a->IdTable[Id];
229 free_entity(a, e_no);
230 for (i = 0; i < 256; i++)
231 {
232 if (a->FlowControlIdTable[i] == Id)
233 a->FlowControlIdTable[i] = 0;
234 }
235 a->IdTable[Id] = 0;
236 this->Id = 0;
237 }
238}
239static byte pr_ready(ADAPTER *a)
240{
241 byte ReadyCount;
242 ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) -
243 a->ram_in(a, &PR_RAM->ReqInput));
244 if (!ReadyCount) {
245 if (!a->ReadyInt) {
246 a->ram_inc(a, &PR_RAM->ReadyInt);
247 a->ReadyInt++;
248 }
249 }
250 return ReadyCount;
251}
252/*------------------------------------------------------------------*/
253/* isdn interrupt handler */
254/*------------------------------------------------------------------*/
255byte pr_dpc(ADAPTER *a)
256{
257 byte Count;
258 RC *RcIn;
259 IND *IndIn;
260 byte c;
261 byte RNRId;
262 byte Rc;
263 byte Ind;
264 /* if return codes are available ... */
265 if ((Count = a->ram_in(a, &PR_RAM->RcOutput)) != 0) {
266 dtrc(dprintf("#Rc=%x", Count));
267 /* get the buffer address of the first return code */
268 RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)];
269 /* for all return codes do ... */
270 while (Count--) {
271 if ((Rc = a->ram_in(a, &RcIn->Rc)) != 0) {
272 dword tmp[2];
273 /*
274 Get extended information, associated with return code
275 */
276 a->ram_in_buffer(a,
277 &RcIn->Reserved2[0],
278 (byte *)&tmp[0],
279 8);
280 /* call return code handler, if it is not our return code */
281 /* the handler returns 2 */
282 /* for all return codes we process, we clear the Rc field */
283 isdn_rc(a,
284 Rc,
285 a->ram_in(a, &RcIn->RcId),
286 a->ram_in(a, &RcIn->RcCh),
287 a->ram_inw(a, &RcIn->Reference),
288 tmp[0], /* type of extended information */
289 tmp[1]); /* extended information */
290 a->ram_out(a, &RcIn->Rc, 0);
291 }
292 /* get buffer address of next return code */
293 RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)];
294 }
295 /* clear all return codes (no chaining!) */
296 a->ram_out(a, &PR_RAM->RcOutput, 0);
297 /* call output function */
298 pr_out(a);
299 }
300 /* clear RNR flag */
301 RNRId = 0;
302 /* if indications are available ... */
303 if ((Count = a->ram_in(a, &PR_RAM->IndOutput)) != 0) {
304 dtrc(dprintf("#Ind=%x", Count));
305 /* get the buffer address of the first indication */
306 IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)];
307 /* for all indications do ... */
308 while (Count--) {
309 /* if the application marks an indication as RNR, all */
310 /* indications from the same Id delivered in this interrupt */
311 /* are marked RNR */
312 if (RNRId && RNRId == a->ram_in(a, &IndIn->IndId)) {
313 a->ram_out(a, &IndIn->Ind, 0);
314 a->ram_out(a, &IndIn->RNR, true);
315 }
316 else {
317 Ind = a->ram_in(a, &IndIn->Ind);
318 if (Ind) {
319 RNRId = 0;
320 /* call indication handler, a return value of 2 means chain */
321 /* a return value of 1 means RNR */
322 /* for all indications we process, we clear the Ind field */
323 c = isdn_ind(a,
324 Ind,
325 a->ram_in(a, &IndIn->IndId),
326 a->ram_in(a, &IndIn->IndCh),
327 &IndIn->RBuffer,
328 a->ram_in(a, &IndIn->MInd),
329 a->ram_inw(a, &IndIn->MLength));
330 if (c == 1) {
331 dtrc(dprintf("RNR"));
332 a->ram_out(a, &IndIn->Ind, 0);
333 RNRId = a->ram_in(a, &IndIn->IndId);
334 a->ram_out(a, &IndIn->RNR, true);
335 }
336 }
337 }
338 /* get buffer address of next indication */
339 IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)];
340 }
341 a->ram_out(a, &PR_RAM->IndOutput, 0);
342 }
343 return false;
344}
345byte scom_test_int(ADAPTER *a)
346{
347 return a->ram_in(a, (void *)0x3fe);
348}
349void scom_clear_int(ADAPTER *a)
350{
351 a->ram_out(a, (void *)0x3fe, 0);
352}
353/*------------------------------------------------------------------*/
354/* return code handler */
355/*------------------------------------------------------------------*/
356static byte isdn_rc(ADAPTER *a,
357 byte Rc,
358 byte Id,
359 byte Ch,
360 word Ref,
361 dword extended_info_type,
362 dword extended_info)
363{
364 ENTITY *this;
365 byte e_no;
366 word i;
367 int cancel_rc;
368#ifdef USE_EXTENDED_DEBUGS
369 {
370 DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
371 }
372#else
373 dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)", Rc, Id, Ch));
374#endif
375 /* check for ready interrupt */
376 if (Rc == READY_INT) {
377 xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 0, 0);
378 if (a->ReadyInt) {
379 a->ReadyInt--;
380 return 0;
381 }
382 return 2;
383 }
384 /* if we know this Id ... */
385 e_no = a->IdTable[Id];
386 if (e_no) {
387 this = entity_ptr(a, e_no);
388 xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 0, a->IdTypeTable[this->No]);
389 this->RcCh = Ch;
390 /* if it is a return code to a REMOVE request, remove the */
391 /* Id from our table */
392 if ((a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_REMOVE_PENDING) &&
393 (Rc == OK)) {
394 if (a->IdTypeTable[e_no] == NL_ID) {
395 if (a->RcExtensionSupported &&
396 (extended_info_type != DIVA_RC_TYPE_REMOVE_COMPLETE)) {
397 dtrc(dprintf("XDI: N-REMOVE, A(%02x) Id:%02x, ignore RC=OK",
398 XDI_A_NR(a), Id));
399 return (0);
400 }
401 if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE)
402 a->RcExtensionSupported = true;
403 }
404 a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING;
405 a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING;
406 free_entity(a, e_no);
407 for (i = 0; i < 256; i++)
408 {
409 if (a->FlowControlIdTable[i] == Id)
410 a->FlowControlIdTable[i] = 0;
411 }
412 a->IdTable[Id] = 0;
413 this->Id = 0;
414 /* ---------------------------------------------------------------
415 If we send N_DISC or N_DISK_ACK after we have received OK_FC
416 then the card will respond with OK_FC and later with RC==OK.
417 If we send N_REMOVE in this state we will receive only RC==OK
418 This will create the state in that the XDI is waiting for the
419 additional RC and does not delivery the RC to the client. This
420 code corrects the counter of outstanding RC's in this case.
421 --------------------------------------------------------------- */
422 if ((this->More & XMOREC) > 1) {
423 this->More &= ~XMOREC;
424 this->More |= 1;
425 dtrc(dprintf("XDI: correct MORE on REMOVE A(%02x) Id:%02x",
426 XDI_A_NR(a), Id));
427 }
428 }
429 if (Rc == OK_FC) {
430 a->FlowControlIdTable[Ch] = Id;
431 a->FlowControlSkipTable[Ch] = false;
432 this->Rc = Rc;
433 this->More &= ~(XBUSY | XMOREC);
434 this->complete = 0xff;
435 xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
436 CALLBACK(a, this);
437 return 0;
438 }
439 /*
440 New protocol code sends return codes that comes from release
441 of flow control condition marked with DIVA_RC_TYPE_OK_FC extended
442 information element type.
443 If like return code arrives then application is able to process
444 all return codes self and XDI should not cances return codes.
445 This return code does not decrement XMOREC partial return code
446 counter due to fact that it was no request for this return code,
447 also XMOREC was not incremented.
448 */
449 if (extended_info_type == DIVA_RC_TYPE_OK_FC) {
450 a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_NO_RC_CANCELLING;
451 this->Rc = Rc;
452 this->complete = 0xff;
453 xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
454 DBG_TRC(("XDI OK_FC A(%02x) Id:%02x Ch:%02x Rc:%02x",
455 XDI_A_NR(a), Id, Ch, Rc))
456 CALLBACK(a, this);
457 return 0;
458 }
459 cancel_rc = !(a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_NO_RC_CANCELLING);
460 if (cancel_rc && (a->FlowControlIdTable[Ch] == Id))
461 {
462 a->FlowControlIdTable[Ch] = 0;
463 if ((Rc != OK) || !a->FlowControlSkipTable[Ch])
464 {
465 this->Rc = Rc;
466 if (Ch == this->ReqCh)
467 {
468 this->More &= ~(XBUSY | XMOREC);
469 this->complete = 0xff;
470 }
471 xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
472 CALLBACK(a, this);
473 }
474 return 0;
475 }
476 if (this->More & XMOREC)
477 this->More--;
478 /* call the application callback function */
479 if (((!cancel_rc) || (this->More & XMOREF)) && !(this->More & XMOREC)) {
480 this->Rc = Rc;
481 this->More &= ~XBUSY;
482 this->complete = 0xff;
483 xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
484 CALLBACK(a, this);
485 }
486 return 0;
487 }
488 /* if it's an ASSIGN return code check if it's a return */
489 /* code to an ASSIGN request from us */
490 if ((Rc & 0xf0) == ASSIGN_RC) {
491 e_no = get_assign(a, Ref);
492 if (e_no) {
493 this = entity_ptr(a, e_no);
494 this->Id = Id;
495 xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 2, a->IdTypeTable[this->No]);
496 /* call the application callback function */
497 this->Rc = Rc;
498 this->More &= ~XBUSY;
499 this->complete = 0xff;
500#if defined(DIVA_ISTREAM) /* { */
501 if ((Rc == ASSIGN_OK) && a->ram_offset &&
502 (a->IdTypeTable[this->No] == NL_ID) &&
503 ((extended_info_type == DIVA_RC_TYPE_RX_DMA) ||
504 (extended_info_type == DIVA_RC_TYPE_CMA_PTR)) &&
505 extended_info) {
506 dword offset = (*(a->ram_offset)) (a);
507 dword tmp[2];
508 extended_info -= offset;
509#ifdef PLATFORM_GT_32BIT
510 a->ram_in_dw(a, (void *)ULongToPtr(extended_info), (dword *)&tmp[0], 2);
511#else
512 a->ram_in_dw(a, (void *)extended_info, (dword *)&tmp[0], 2);
513#endif
514 a->tx_stream[Id] = tmp[0];
515 a->rx_stream[Id] = tmp[1];
516 if (extended_info_type == DIVA_RC_TYPE_RX_DMA) {
517 DBG_TRC(("Id=0x%x RxDMA=%08x:%08x",
518 Id, a->tx_stream[Id], a->rx_stream[Id]))
519 a->misc_flags_table[this->No] |= DIVA_MISC_FLAGS_RX_DMA;
520 } else {
521 DBG_TRC(("Id=0x%x CMA=%08x:%08x",
522 Id, a->tx_stream[Id], a->rx_stream[Id]))
523 a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
524 a->rx_pos[Id] = 0;
525 a->rx_stream[Id] -= offset;
526 }
527 a->tx_pos[Id] = 0;
528 a->tx_stream[Id] -= offset;
529 } else {
530 a->tx_stream[Id] = 0;
531 a->rx_stream[Id] = 0;
532 a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
533 }
534#endif /* } */
535 CALLBACK(a, this);
536 if (Rc == ASSIGN_OK) {
537 a->IdTable[Id] = e_no;
538 }
539 else
540 {
541 free_entity(a, e_no);
542 for (i = 0; i < 256; i++)
543 {
544 if (a->FlowControlIdTable[i] == Id)
545 a->FlowControlIdTable[i] = 0;
546 }
547 a->IdTable[Id] = 0;
548 this->Id = 0;
549 }
550 return 1;
551 }
552 }
553 return 2;
554}
555/*------------------------------------------------------------------*/
556/* indication handler */
557/*------------------------------------------------------------------*/
558static byte isdn_ind(ADAPTER *a,
559 byte Ind,
560 byte Id,
561 byte Ch,
562 PBUFFER *RBuffer,
563 byte MInd,
564 word MLength)
565{
566 ENTITY *this;
567 word clength;
568 word offset;
569 BUFFERS *R;
570 byte *cma = NULL;
571#ifdef USE_EXTENDED_DEBUGS
572 {
573 DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
574 }
575#else
576 dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)", Ind, Id, Ch));
577#endif
578 if (a->IdTable[Id]) {
579 this = entity_ptr(a, a->IdTable[Id]);
580 this->IndCh = Ch;
581 xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
582 0/* rnr_valid */, 0 /* rnr */, a->IdTypeTable[this->No]);
583 /* if the Receive More flag is not yet set, this is the */
584 /* first buffer of the packet */
585 if (this->RCurrent == 0xff) {
586 /* check for receive buffer chaining */
587 if (Ind == this->MInd) {
588 this->complete = 0;
589 this->Ind = MInd;
590 }
591 else {
592 this->complete = 1;
593 this->Ind = Ind;
594 }
595 /* call the application callback function for the receive */
596 /* look ahead */
597 this->RLength = MLength;
598#if defined(DIVA_ISTREAM)
599 if ((a->rx_stream[this->Id] ||
600 (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA)) &&
601 ((Ind == N_DATA) ||
602 (a->protocol_capabilities & PROTCAP_CMA_ALLPR))) {
603 PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io;
604 if (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA) {
605#if defined(DIVA_IDI_RX_DMA)
606 dword d;
607 diva_get_dma_map_entry(\
608 (struct _diva_dma_map_entry *)IoAdapter->dma_map,
609 (int)a->rx_stream[this->Id], (void **)&cma, &d);
610#else
611 cma = &a->stream_buffer[0];
612 cma[0] = cma[1] = cma[2] = cma[3] = 0;
613#endif
614 this->RLength = MLength = (word)*(dword *)cma;
615 cma += 4;
616 } else {
617 int final = 0;
618 cma = &a->stream_buffer[0];
619 this->RLength = MLength = (word)diva_istream_read(a,
620 Id,
621 cma,
622 sizeof(a->stream_buffer),
623 &final, NULL, NULL);
624 }
625 IoAdapter->RBuffer.length = min(MLength, (word)270);
626 if (IoAdapter->RBuffer.length != MLength) {
627 this->complete = 0;
628 } else {
629 this->complete = 1;
630 }
631 memcpy(IoAdapter->RBuffer.P, cma, IoAdapter->RBuffer.length);
632 this->RBuffer = (DBUFFER *)&IoAdapter->RBuffer;
633 }
634#endif
635 if (!cma) {
636 a->ram_look_ahead(a, RBuffer, this);
637 }
638 this->RNum = 0;
639 CALLBACK(a, this);
640 /* map entity ptr, selector could be re-mapped by call to */
641 /* IDI from within callback */
642 this = entity_ptr(a, a->IdTable[Id]);
643 xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
644 1/* rnr_valid */, this->RNR/* rnr */, a->IdTypeTable[this->No]);
645 /* check for RNR */
646 if (this->RNR == 1) {
647 this->RNR = 0;
648 return 1;
649 }
650 /* if no buffers are provided by the application, the */
651 /* application want to copy the data itself including */
652 /* N_MDATA/LL_MDATA chaining */
653 if (!this->RNR && !this->RNum) {
654 xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
655 2/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
656 return 0;
657 }
658 /* if there is no RNR, set the More flag */
659 this->RCurrent = 0;
660 this->ROffset = 0;
661 }
662 if (this->RNR == 2) {
663 if (Ind != this->MInd) {
664 this->RCurrent = 0xff;
665 this->RNR = 0;
666 }
667 return 0;
668 }
669 /* if we have received buffers from the application, copy */
670 /* the data into these buffers */
671 offset = 0;
672 R = PTR_R(a, this);
673 do {
674 if (this->ROffset == R[this->RCurrent].PLength) {
675 this->ROffset = 0;
676 this->RCurrent++;
677 }
678 if (cma) {
679 clength = min(MLength, (word)(R[this->RCurrent].PLength-this->ROffset));
680 } else {
681 clength = min(a->ram_inw(a, &RBuffer->length)-offset,
682 R[this->RCurrent].PLength-this->ROffset);
683 }
684 if (R[this->RCurrent].P) {
685 if (cma) {
686 memcpy(PTR_P(a, this, &R[this->RCurrent].P[this->ROffset]),
687 &cma[offset],
688 clength);
689 } else {
690 a->ram_in_buffer(a,
691 &RBuffer->P[offset],
692 PTR_P(a, this, &R[this->RCurrent].P[this->ROffset]),
693 clength);
694 }
695 }
696 offset += clength;
697 this->ROffset += clength;
698 if (cma) {
699 if (offset >= MLength) {
700 break;
701 }
702 continue;
703 }
704 } while (offset < (a->ram_inw(a, &RBuffer->length)));
705 /* if it's the last buffer of the packet, call the */
706 /* application callback function for the receive complete */
707 /* call */
708 if (Ind != this->MInd) {
709 R[this->RCurrent].PLength = this->ROffset;
710 if (this->ROffset) this->RCurrent++;
711 this->RNum = this->RCurrent;
712 this->RCurrent = 0xff;
713 this->Ind = Ind;
714 this->complete = 2;
715 xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
716 3/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
717 CALLBACK(a, this);
718 }
719 return 0;
720 }
721 return 2;
722}
723#if defined(XDI_USE_XLOG)
724/* -----------------------------------------------------------
725 This function works in the same way as xlog on the
726 active board
727 ----------------------------------------------------------- */
728static void xdi_xlog(byte *msg, word code, int length) {
729 xdi_dbg_xlog("\x00\x02", msg, code, length);
730}
731#endif
732/* -----------------------------------------------------------
733 This function writes the information about the Return Code
734 processing in the trace buffer. Trace ID is 221.
735 INPUT:
736 Adapter - system unicue adapter number (0 ... 255)
737 Id - Id of the entity that had sent this return code
738 Ch - Channel of the entity that had sent this return code
739 Rc - return code value
740 cb: (0...2)
741 switch (cb) {
742 case 0: printf ("DELIVERY"); break;
743 case 1: printf ("CALLBACK"); break;
744 case 2: printf ("ASSIGN"); break;
745 }
746 DELIVERY - have entered isdn_rc with this RC
747 CALLBACK - about to make callback to the application
748 for this RC
749 ASSIGN - about to make callback for RC that is result
750 of ASSIGN request. It is no DELIVERY message
751 before of this message
752 type - the Id that was sent by the ASSIGN of this entity.
753 This should be global Id like NL_ID, DSIG_ID, MAN_ID.
754 An unknown Id will cause "?-" in the front of the request.
755 In this case the log.c is to be extended.
756 ----------------------------------------------------------- */
757static void xdi_xlog_rc_event(byte Adapter,
758 byte Id, byte Ch, byte Rc, byte cb, byte type) {
759#if defined(XDI_USE_XLOG)
760 word LogInfo[4];
761 PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
762 PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
763 PUT_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
764 PUT_WORD(&LogInfo[3], cb);
765 xdi_xlog((byte *)&LogInfo[0], 221, sizeof(LogInfo));
766#endif
767}
768/* ------------------------------------------------------------------------
769 This function writes the information about the request processing
770 in the trace buffer. Trace ID is 220.
771 INPUT:
772 Adapter - system unicue adapter number (0 ... 255)
773 Id - Id of the entity that had sent this request
774 Ch - Channel of the entity that had sent this request
775 Req - Code of the request
776 type - the Id that was sent by the ASSIGN of this entity.
777 This should be global Id like NL_ID, DSIG_ID, MAN_ID.
778 An unknown Id will cause "?-" in the front of the request.
779 In this case the log.c is to be extended.
780 ------------------------------------------------------------------------ */
781static void xdi_xlog_request(byte Adapter, byte Id,
782 byte Ch, byte Req, byte type) {
783#if defined(XDI_USE_XLOG)
784 word LogInfo[3];
785 PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
786 PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
787 PUT_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
788 xdi_xlog((byte *)&LogInfo[0], 220, sizeof(LogInfo));
789#endif
790}
791/* ------------------------------------------------------------------------
792 This function writes the information about the indication processing
793 in the trace buffer. Trace ID is 222.
794 INPUT:
795 Adapter - system unicue adapter number (0 ... 255)
796 Id - Id of the entity that had sent this indication
797 Ch - Channel of the entity that had sent this indication
798 Ind - Code of the indication
799 rnr_valid: (0 .. 3) supported
800 switch (rnr_valid) {
801 case 0: printf ("DELIVERY"); break;
802 case 1: printf ("RNR=%d", rnr);
803 case 2: printf ("RNum=0");
804 case 3: printf ("COMPLETE");
805 }
806 DELIVERY - indication entered isdn_rc function
807 RNR=... - application had returned RNR=... after the
808 look ahead callback
809 RNum=0 - application had not returned any buffer to copy
810 this indication and will copy it self
811 COMPLETE - XDI had copied the data to the buffers provided
812 bu the application and is about to issue the
813 final callback
814 rnr: Look case 1 of the rnr_valid
815 type: the Id that was sent by the ASSIGN of this entity. This should
816 be global Id like NL_ID, DSIG_ID, MAN_ID. An unknown Id will
817 cause "?-" in the front of the request. In this case the
818 log.c is to be extended.
819 ------------------------------------------------------------------------ */
820static void xdi_xlog_ind(byte Adapter,
821 byte Id,
822 byte Ch,
823 byte Ind,
824 byte rnr_valid,
825 byte rnr,
826 byte type) {
827#if defined(XDI_USE_XLOG)
828 word LogInfo[4];
829 PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
830 PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
831 PUT_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
832 PUT_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
833 xdi_xlog((byte *)&LogInfo[0], 222, sizeof(LogInfo));
834#endif
835}
diff --git a/drivers/isdn/hardware/eicon/di.h b/drivers/isdn/hardware/eicon/di.h
deleted file mode 100644
index ff26c65631d6..000000000000
--- a/drivers/isdn/hardware/eicon/di.h
+++ /dev/null
@@ -1,118 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26/*
27 * some macros for detailed trace management
28 */
29#include "di_dbg.h"
30/*****************************************************************************/
31#define XMOREC 0x1f
32#define XMOREF 0x20
33#define XBUSY 0x40
34#define RMORE 0x80
35#define DIVA_MISC_FLAGS_REMOVE_PENDING 0x01
36#define DIVA_MISC_FLAGS_NO_RC_CANCELLING 0x02
37#define DIVA_MISC_FLAGS_RX_DMA 0x04
38/* structure for all information we have to keep on a per */
39/* adapater basis */
40typedef struct adapter_s ADAPTER;
41struct adapter_s {
42 void *io;
43 byte IdTable[256];
44 byte IdTypeTable[256];
45 byte FlowControlIdTable[256];
46 byte FlowControlSkipTable[256];
47 byte ReadyInt;
48 byte RcExtensionSupported;
49 byte misc_flags_table[256];
50 dword protocol_capabilities;
51 byte (*ram_in)(ADAPTER *a, void *adr);
52 word (*ram_inw)(ADAPTER *a, void *adr);
53 void (*ram_in_buffer)(ADAPTER *a, void *adr, void *P, word length);
54 void (*ram_look_ahead)(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
55 void (*ram_out)(ADAPTER *a, void *adr, byte data);
56 void (*ram_outw)(ADAPTER *a, void *adr, word data);
57 void (*ram_out_buffer)(ADAPTER *a, void *adr, void *P, word length);
58 void (*ram_inc)(ADAPTER *a, void *adr);
59#if defined(DIVA_ISTREAM)
60 dword rx_stream[256];
61 dword tx_stream[256];
62 word tx_pos[256];
63 word rx_pos[256];
64 byte stream_buffer[2512];
65 dword (*ram_offset)(ADAPTER *a);
66 void (*ram_out_dw)(ADAPTER *a,
67 void *addr,
68 const dword *data,
69 int dwords);
70 void (*ram_in_dw)(ADAPTER *a,
71 void *addr,
72 dword *data,
73 int dwords);
74 void (*istream_wakeup)(ADAPTER *a);
75#else
76 byte stream_buffer[4];
77#endif
78};
79/*------------------------------------------------------------------*/
80/* public functions of IDI common code */
81/*------------------------------------------------------------------*/
82void pr_out(ADAPTER *a);
83byte pr_dpc(ADAPTER *a);
84byte scom_test_int(ADAPTER *a);
85void scom_clear_int(ADAPTER *a);
86/*------------------------------------------------------------------*/
87/* OS specific functions used by IDI common code */
88/*------------------------------------------------------------------*/
89void free_entity(ADAPTER *a, byte e_no);
90void assign_queue(ADAPTER *a, byte e_no, word ref);
91byte get_assign(ADAPTER *a, word ref);
92void req_queue(ADAPTER *a, byte e_no);
93byte look_req(ADAPTER *a);
94void next_req(ADAPTER *a);
95ENTITY *entity_ptr(ADAPTER *a, byte e_no);
96#if defined(DIVA_ISTREAM)
97struct _diva_xdi_stream_interface;
98void diva_xdi_provide_istream_info(ADAPTER *a,
99 struct _diva_xdi_stream_interface *pI);
100void pr_stream(ADAPTER *a);
101int diva_istream_write(void *context,
102 int Id,
103 void *data,
104 int length,
105 int final,
106 byte usr1,
107 byte usr2);
108int diva_istream_read(void *context,
109 int Id,
110 void *data,
111 int max_length,
112 int *final,
113 byte *usr1,
114 byte *usr2);
115#if defined(DIVA_IDI_RX_DMA)
116#include "diva_dma.h"
117#endif
118#endif
diff --git a/drivers/isdn/hardware/eicon/di_dbg.h b/drivers/isdn/hardware/eicon/di_dbg.h
deleted file mode 100644
index 1380b60e526e..000000000000
--- a/drivers/isdn/hardware/eicon/di_dbg.h
+++ /dev/null
@@ -1,37 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_DI_DBG_INC__
27#define __DIVA_DI_DBG_INC__
28#if !defined(dtrc)
29#define dtrc(a)
30#endif
31#if !defined(dbug)
32#define dbug(a)
33#endif
34#if !defined USE_EXTENDED_DEBUGS
35extern void (*dprintf)(char*, ...);
36#endif
37#endif
diff --git a/drivers/isdn/hardware/eicon/di_defs.h b/drivers/isdn/hardware/eicon/di_defs.h
deleted file mode 100644
index a5094d221086..000000000000
--- a/drivers/isdn/hardware/eicon/di_defs.h
+++ /dev/null
@@ -1,181 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef _DI_DEFS_
27#define _DI_DEFS_
28/* typedefs for our data structures */
29typedef struct get_name_s GET_NAME;
30/* The entity_s structure is used to pass all
31 parameters between application and IDI */
32typedef struct entity_s ENTITY;
33typedef struct buffers_s BUFFERS;
34typedef struct postcall_s POSTCALL;
35typedef struct get_para_s GET_PARA;
36#define BOARD_NAME_LENGTH 9
37#define IDI_CALL_LINK_T
38#define IDI_CALL_ENTITY_T
39/* typedef void ( * IDI_CALL)(ENTITY *); */
40/* --------------------------------------------------------
41 IDI_CALL
42 -------------------------------------------------------- */
43typedef void (IDI_CALL_LINK_T *IDI_CALL)(ENTITY IDI_CALL_ENTITY_T *);
44typedef struct {
45 word length; /* length of data/parameter field */
46 byte P[270]; /* data/parameter field */
47} DBUFFER;
48struct get_name_s {
49 word command; /* command = 0x0100 */
50 byte name[BOARD_NAME_LENGTH];
51};
52struct postcall_s {
53 word command; /* command = 0x0300 */
54 word dummy; /* not used */
55 void (*callback)(void *); /* call back */
56 void *context; /* context pointer */
57};
58#define REQ_PARA 0x0600 /* request command line parameters */
59#define REQ_PARA_LEN 1 /* number of data bytes */
60#define L1_STARTUP_DOWN_POS 0 /* '-y' command line parameter in......*/
61#define L1_STARTUP_DOWN_MSK 0x01 /* first byte position (index 0) with value 0x01 */
62struct get_para_s {
63 word command; /* command = 0x0600 */
64 byte len; /* max length of para field in bytes */
65 byte para[REQ_PARA_LEN]; /* parameter field */
66};
67struct buffers_s {
68 word PLength;
69 byte *P;
70};
71struct entity_s {
72 byte Req; /* pending request */
73 byte Rc; /* return code received */
74 byte Ind; /* indication received */
75 byte ReqCh; /* channel of current Req */
76 byte RcCh; /* channel of current Rc */
77 byte IndCh; /* channel of current Ind */
78 byte Id; /* ID used by this entity */
79 byte GlobalId; /* reserved field */
80 byte XNum; /* number of X-buffers */
81 byte RNum; /* number of R-buffers */
82 BUFFERS *X; /* pointer to X-buffer list */
83 BUFFERS *R; /* pointer to R-buffer list */
84 word RLength; /* length of current R-data */
85 DBUFFER *RBuffer; /* buffer of current R-data */
86 byte RNR; /* receive not ready flag */
87 byte complete; /* receive complete status */
88 IDI_CALL callback;
89 word user[2];
90 /* fields used by the driver internally */
91 byte No; /* entity number */
92 byte reserved2; /* reserved field */
93 byte More; /* R/X More flags */
94 byte MInd; /* MDATA coding for this ID */
95 byte XCurrent; /* current transmit buffer */
96 byte RCurrent; /* current receive buffer */
97 word XOffset; /* offset in x-buffer */
98 word ROffset; /* offset in r-buffer */
99};
100typedef struct {
101 byte type;
102 byte channels;
103 word features;
104 IDI_CALL request;
105} DESCRIPTOR;
106/* descriptor type field coding */
107#define IDI_ADAPTER_S 1
108#define IDI_ADAPTER_PR 2
109#define IDI_ADAPTER_DIVA 3
110#define IDI_ADAPTER_MAESTRA 4
111#define IDI_VADAPTER 0x40
112#define IDI_DRIVER 0x80
113#define IDI_DADAPTER 0xfd
114#define IDI_DIDDPNP 0xfe
115#define IDI_DIMAINT 0xff
116/* Hardware IDs ISA PNP */
117#define HW_ID_DIVA_PRO 3 /* same as IDI_ADAPTER_DIVA */
118#define HW_ID_MAESTRA 4 /* same as IDI_ADAPTER_MAESTRA */
119#define HW_ID_PICCOLA 5
120#define HW_ID_DIVA_PRO20 6
121#define HW_ID_DIVA20 7
122#define HW_ID_DIVA_PRO20_U 8
123#define HW_ID_DIVA20_U 9
124#define HW_ID_DIVA30 10
125#define HW_ID_DIVA30_U 11
126/* Hardware IDs PCI */
127#define HW_ID_EICON_PCI 0x1133
128#define HW_ID_SIEMENS_PCI 0x8001 /* unused SubVendor ID for Siemens Cornet-N cards */
129#define HW_ID_PROTTYPE_CORNETN 0x0014 /* SubDevice ID for Siemens Cornet-N cards */
130#define HW_ID_FUJITSU_SIEMENS_PCI 0x110A /* SubVendor ID for Fujitsu Siemens */
131#define HW_ID_GS03_PCI 0x0021 /* SubDevice ID for Fujitsu Siemens ISDN S0 card */
132#define HW_ID_DIVA_PRO20_PCI 0xe001
133#define HW_ID_DIVA20_PCI 0xe002
134#define HW_ID_DIVA_PRO20_PCI_U 0xe003
135#define HW_ID_DIVA20_PCI_U 0xe004
136#define HW_ID_DIVA201_PCI 0xe005
137#define HW_ID_DIVA_CT_ST 0xe006
138#define HW_ID_DIVA_CT_U 0xe007
139#define HW_ID_DIVA_CTL_ST 0xe008
140#define HW_ID_DIVA_CTL_U 0xe009
141#define HW_ID_DIVA_ISDN_V90_PCI 0xe00a
142#define HW_ID_DIVA202_PCI_ST 0xe00b
143#define HW_ID_DIVA202_PCI_U 0xe00c
144#define HW_ID_DIVA_PRO30_PCI 0xe00d
145#define HW_ID_MAESTRA_PCI 0xe010
146#define HW_ID_MAESTRAQ_PCI 0xe012
147#define HW_ID_DSRV_Q8M_V2_PCI 0xe013
148#define HW_ID_MAESTRAP_PCI 0xe014
149#define HW_ID_DSRV_P30M_V2_PCI 0xe015
150#define HW_ID_DSRV_VOICE_Q8M_PCI 0xe016
151#define HW_ID_DSRV_VOICE_Q8M_V2_PCI 0xe017
152#define HW_ID_DSRV_B2M_V2_PCI 0xe018
153#define HW_ID_DSRV_VOICE_P30M_V2_PCI 0xe019
154#define HW_ID_DSRV_B2F_PCI 0xe01a
155#define HW_ID_DSRV_VOICE_B2M_V2_PCI 0xe01b
156/* Hardware IDs USB */
157#define EICON_USB_VENDOR_ID 0x071D
158#define HW_ID_DIVA_USB_REV1 0x1000
159#define HW_ID_DIVA_USB_REV2 0x1003
160#define HW_ID_TELEDAT_SURF_USB_REV2 0x1004
161#define HW_ID_TELEDAT_SURF_USB_REV1 0x2000
162/* --------------------------------------------------------------------------
163 Adapter array change notification framework
164 -------------------------------------------------------------------------- */
165typedef void (IDI_CALL_LINK_T *didd_adapter_change_callback_t)(void IDI_CALL_ENTITY_T *context, DESCRIPTOR *adapter, int removal);
166/* -------------------------------------------------------------------------- */
167#define DI_VOICE 0x0 /* obsolete define */
168#define DI_FAX3 0x1
169#define DI_MODEM 0x2
170#define DI_POST 0x4
171#define DI_V110 0x8
172#define DI_V120 0x10
173#define DI_POTS 0x20
174#define DI_CODEC 0x40
175#define DI_MANAGE 0x80
176#define DI_V_42 0x0100
177#define DI_EXTD_FAX 0x0200 /* Extended FAX (ECM, 2D, T.6, Polling) */
178#define DI_AT_PARSER 0x0400 /* Build-in AT Parser in the L2 */
179#define DI_VOICE_OVER_IP 0x0800 /* Voice over IP support */
180typedef void (IDI_CALL_LINK_T *_IDI_CALL)(void *, ENTITY *);
181#endif
diff --git a/drivers/isdn/hardware/eicon/did_vers.h b/drivers/isdn/hardware/eicon/did_vers.h
deleted file mode 100644
index fa8db8249235..000000000000
--- a/drivers/isdn/hardware/eicon/did_vers.h
+++ /dev/null
@@ -1,26 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26static char diva_didd_common_code_build[] = "102-51";
diff --git a/drivers/isdn/hardware/eicon/diddfunc.c b/drivers/isdn/hardware/eicon/diddfunc.c
deleted file mode 100644
index b0b23ed8b374..000000000000
--- a/drivers/isdn/hardware/eicon/diddfunc.c
+++ /dev/null
@@ -1,115 +0,0 @@
1/* $Id: diddfunc.c,v 1.14.6.2 2004/08/28 20:03:53 armin Exp $
2 *
3 * DIDD Interface module for Eicon active cards.
4 *
5 * Functions are in dadapter.c
6 *
7 * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
8 * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
9 *
10 * This software may be used and distributed according to the terms
11 * of the GNU General Public License, incorporated herein by reference.
12 */
13
14#include "platform.h"
15#include "di_defs.h"
16#include "dadapter.h"
17#include "divasync.h"
18
19#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
20#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
21
22
23extern void DIVA_DIDD_Read(void *, int);
24extern char *DRIVERRELEASE_DIDD;
25static dword notify_handle;
26static DESCRIPTOR _DAdapter;
27
28/*
29 * didd callback function
30 */
31static void *didd_callback(void *context, DESCRIPTOR *adapter,
32 int removal)
33{
34 if (adapter->type == IDI_DADAPTER) {
35 DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."))
36 return (NULL);
37 } else if (adapter->type == IDI_DIMAINT) {
38 if (removal) {
39 DbgDeregister();
40 } else {
41 DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
42 }
43 }
44 return (NULL);
45}
46
47/*
48 * connect to didd
49 */
50static int __init connect_didd(void)
51{
52 int x = 0;
53 int dadapter = 0;
54 IDI_SYNC_REQ req;
55 DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
56
57 DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
58
59 for (x = 0; x < MAX_DESCRIPTORS; x++) {
60 if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */
61 dadapter = 1;
62 memcpy(&_DAdapter, &DIDD_Table[x], sizeof(_DAdapter));
63 req.didd_notify.e.Req = 0;
64 req.didd_notify.e.Rc =
65 IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
66 req.didd_notify.info.callback = (void *)didd_callback;
67 req.didd_notify.info.context = NULL;
68 _DAdapter.request((ENTITY *)&req);
69 if (req.didd_notify.e.Rc != 0xff)
70 return (0);
71 notify_handle = req.didd_notify.info.handle;
72 } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
73 DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
74 }
75 }
76 return (dadapter);
77}
78
79/*
80 * disconnect from didd
81 */
82static void __exit disconnect_didd(void)
83{
84 IDI_SYNC_REQ req;
85
86 req.didd_notify.e.Req = 0;
87 req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
88 req.didd_notify.info.handle = notify_handle;
89 _DAdapter.request((ENTITY *)&req);
90}
91
92/*
93 * init
94 */
95int __init diddfunc_init(void)
96{
97 diva_didd_load_time_init();
98
99 if (!connect_didd()) {
100 DBG_ERR(("init: failed to connect to DIDD."))
101 diva_didd_load_time_finit();
102 return (0);
103 }
104 return (1);
105}
106
107/*
108 * finit
109 */
110void __exit diddfunc_finit(void)
111{
112 DbgDeregister();
113 disconnect_didd();
114 diva_didd_load_time_finit();
115}
diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c
deleted file mode 100644
index 1b25d8bc153a..000000000000
--- a/drivers/isdn/hardware/eicon/diva.c
+++ /dev/null
@@ -1,666 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/* $Id: diva.c,v 1.21.4.1 2004/05/08 14:33:43 armin Exp $ */
3
4#define CARDTYPE_H_WANT_DATA 1
5#define CARDTYPE_H_WANT_IDI_DATA 0
6#define CARDTYPE_H_WANT_RESOURCE_DATA 0
7#define CARDTYPE_H_WANT_FILE_DATA 0
8
9#include "platform.h"
10#include "debuglib.h"
11#include "cardtype.h"
12#include "pc.h"
13#include "di_defs.h"
14#include "di.h"
15#include "io.h"
16#include "pc_maint.h"
17#include "xdi_msg.h"
18#include "xdi_adapter.h"
19#include "diva_pci.h"
20#include "diva.h"
21
22#ifdef CONFIG_ISDN_DIVAS_PRIPCI
23#include "os_pri.h"
24#endif
25#ifdef CONFIG_ISDN_DIVAS_BRIPCI
26#include "os_bri.h"
27#include "os_4bri.h"
28#endif
29
30PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
31extern IDI_CALL Requests[MAX_ADAPTER];
32extern int create_adapter_proc(diva_os_xdi_adapter_t *a);
33extern void remove_adapter_proc(diva_os_xdi_adapter_t *a);
34
35#define DivaIdiReqFunc(N) \
36 static void DivaIdiRequest##N(ENTITY *e) \
37 { if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); }
38
39/*
40** Create own 32 Adapters
41*/
42DivaIdiReqFunc(0)
43DivaIdiReqFunc(1)
44DivaIdiReqFunc(2)
45DivaIdiReqFunc(3)
46DivaIdiReqFunc(4)
47DivaIdiReqFunc(5)
48DivaIdiReqFunc(6)
49DivaIdiReqFunc(7)
50DivaIdiReqFunc(8)
51DivaIdiReqFunc(9)
52DivaIdiReqFunc(10)
53DivaIdiReqFunc(11)
54DivaIdiReqFunc(12)
55DivaIdiReqFunc(13)
56DivaIdiReqFunc(14)
57DivaIdiReqFunc(15)
58DivaIdiReqFunc(16)
59DivaIdiReqFunc(17)
60DivaIdiReqFunc(18)
61DivaIdiReqFunc(19)
62DivaIdiReqFunc(20)
63DivaIdiReqFunc(21)
64DivaIdiReqFunc(22)
65DivaIdiReqFunc(23)
66DivaIdiReqFunc(24)
67DivaIdiReqFunc(25)
68DivaIdiReqFunc(26)
69DivaIdiReqFunc(27)
70DivaIdiReqFunc(28)
71DivaIdiReqFunc(29)
72DivaIdiReqFunc(30)
73DivaIdiReqFunc(31)
74
75/*
76** LOCALS
77*/
78static LIST_HEAD(adapter_queue);
79
80typedef struct _diva_get_xlog {
81 word command;
82 byte req;
83 byte rc;
84 byte data[sizeof(struct mi_pc_maint)];
85} diva_get_xlog_t;
86
87typedef struct _diva_supported_cards_info {
88 int CardOrdinal;
89 diva_init_card_proc_t init_card;
90} diva_supported_cards_info_t;
91
92static diva_supported_cards_info_t divas_supported_cards[] = {
93#ifdef CONFIG_ISDN_DIVAS_PRIPCI
94 /*
95 PRI Cards
96 */
97 {CARDTYPE_DIVASRV_P_30M_PCI, diva_pri_init_card},
98 /*
99 PRI Rev.2 Cards
100 */
101 {CARDTYPE_DIVASRV_P_30M_V2_PCI, diva_pri_init_card},
102 /*
103 PRI Rev.2 VoIP Cards
104 */
105 {CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI, diva_pri_init_card},
106#endif
107#ifdef CONFIG_ISDN_DIVAS_BRIPCI
108 /*
109 4BRI Rev 1 Cards
110 */
111 {CARDTYPE_DIVASRV_Q_8M_PCI, diva_4bri_init_card},
112 {CARDTYPE_DIVASRV_VOICE_Q_8M_PCI, diva_4bri_init_card},
113 /*
114 4BRI Rev 2 Cards
115 */
116 {CARDTYPE_DIVASRV_Q_8M_V2_PCI, diva_4bri_init_card},
117 {CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI, diva_4bri_init_card},
118 /*
119 4BRI Based BRI Rev 2 Cards
120 */
121 {CARDTYPE_DIVASRV_B_2M_V2_PCI, diva_4bri_init_card},
122 {CARDTYPE_DIVASRV_B_2F_PCI, diva_4bri_init_card},
123 {CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI, diva_4bri_init_card},
124 /*
125 BRI
126 */
127 {CARDTYPE_MAESTRA_PCI, diva_bri_init_card},
128#endif
129
130 /*
131 EOL
132 */
133 {-1}
134};
135
136static void diva_init_request_array(void);
137static void *divas_create_pci_card(int handle, void *pci_dev_handle);
138
139static diva_os_spin_lock_t adapter_lock;
140
141static int diva_find_free_adapters(int base, int nr)
142{
143 int i;
144
145 for (i = 0; i < nr; i++) {
146 if (IoAdapters[base + i]) {
147 return (-1);
148 }
149 }
150
151 return (0);
152}
153
154static diva_os_xdi_adapter_t *diva_q_get_next(struct list_head *what)
155{
156 diva_os_xdi_adapter_t *a = NULL;
157
158 if (what && (what->next != &adapter_queue))
159 a = list_entry(what->next, diva_os_xdi_adapter_t, link);
160
161 return (a);
162}
163
164/* --------------------------------------------------------------------------
165 Add card to the card list
166 -------------------------------------------------------------------------- */
167void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
168{
169 diva_os_spin_lock_magic_t old_irql;
170 diva_os_xdi_adapter_t *pdiva, *pa;
171 int i, j, max, nr;
172
173 for (i = 0; divas_supported_cards[i].CardOrdinal != -1; i++) {
174 if (divas_supported_cards[i].CardOrdinal == CardOrdinal) {
175 if (!(pdiva = divas_create_pci_card(i, pdev))) {
176 return NULL;
177 }
178 switch (CardOrdinal) {
179 case CARDTYPE_DIVASRV_Q_8M_PCI:
180 case CARDTYPE_DIVASRV_VOICE_Q_8M_PCI:
181 case CARDTYPE_DIVASRV_Q_8M_V2_PCI:
182 case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI:
183 max = MAX_ADAPTER - 4;
184 nr = 4;
185 break;
186
187 default:
188 max = MAX_ADAPTER;
189 nr = 1;
190 }
191
192 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
193
194 for (i = 0; i < max; i++) {
195 if (!diva_find_free_adapters(i, nr)) {
196 pdiva->controller = i + 1;
197 pdiva->xdi_adapter.ANum = pdiva->controller;
198 IoAdapters[i] = &pdiva->xdi_adapter;
199 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
200 create_adapter_proc(pdiva); /* add adapter to proc file system */
201
202 DBG_LOG(("add %s:%d",
203 CardProperties
204 [CardOrdinal].Name,
205 pdiva->controller))
206
207 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
208 pa = pdiva;
209 for (j = 1; j < nr; j++) { /* slave adapters, if any */
210 pa = diva_q_get_next(&pa->link);
211 if (pa && !pa->interface.cleanup_adapter_proc) {
212 pa->controller = i + 1 + j;
213 pa->xdi_adapter.ANum = pa->controller;
214 IoAdapters[i + j] = &pa->xdi_adapter;
215 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
216 DBG_LOG(("add slave adapter (%d)",
217 pa->controller))
218 create_adapter_proc(pa); /* add adapter to proc file system */
219 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
220 } else {
221 DBG_ERR(("slave adapter problem"))
222 break;
223 }
224 }
225
226 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
227 return (pdiva);
228 }
229 }
230
231 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
232
233 /*
234 Not able to add adapter - remove it and return error
235 */
236 DBG_ERR(("can not alloc request array"))
237 diva_driver_remove_card(pdiva);
238
239 return NULL;
240 }
241 }
242
243 return NULL;
244}
245
246/* --------------------------------------------------------------------------
247 Called on driver load, MAIN, main, DriverEntry
248 -------------------------------------------------------------------------- */
249int divasa_xdi_driver_entry(void)
250{
251 diva_os_initialize_spin_lock(&adapter_lock, "adapter");
252 memset(&IoAdapters[0], 0x00, sizeof(IoAdapters));
253 diva_init_request_array();
254
255 return (0);
256}
257
258/* --------------------------------------------------------------------------
259 Remove adapter from list
260 -------------------------------------------------------------------------- */
261static diva_os_xdi_adapter_t *get_and_remove_from_queue(void)
262{
263 diva_os_spin_lock_magic_t old_irql;
264 diva_os_xdi_adapter_t *a = NULL;
265
266 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "driver_unload");
267
268 if (!list_empty(&adapter_queue)) {
269 a = list_entry(adapter_queue.next, diva_os_xdi_adapter_t, link);
270 list_del(adapter_queue.next);
271 }
272
273 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "driver_unload");
274 return (a);
275}
276
277/* --------------------------------------------------------------------------
278 Remove card from the card list
279 -------------------------------------------------------------------------- */
280void diva_driver_remove_card(void *pdiva)
281{
282 diva_os_spin_lock_magic_t old_irql;
283 diva_os_xdi_adapter_t *a[4];
284 diva_os_xdi_adapter_t *pa;
285 int i;
286
287 pa = a[0] = (diva_os_xdi_adapter_t *) pdiva;
288 a[1] = a[2] = a[3] = NULL;
289
290 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "remode adapter");
291
292 for (i = 1; i < 4; i++) {
293 if ((pa = diva_q_get_next(&pa->link))
294 && !pa->interface.cleanup_adapter_proc) {
295 a[i] = pa;
296 } else {
297 break;
298 }
299 }
300
301 for (i = 0; ((i < 4) && a[i]); i++) {
302 list_del(&a[i]->link);
303 }
304
305 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "driver_unload");
306
307 (*(a[0]->interface.cleanup_adapter_proc)) (a[0]);
308
309 for (i = 0; i < 4; i++) {
310 if (a[i]) {
311 if (a[i]->controller) {
312 DBG_LOG(("remove adapter (%d)",
313 a[i]->controller)) IoAdapters[a[i]->controller - 1] = NULL;
314 remove_adapter_proc(a[i]);
315 }
316 diva_os_free(0, a[i]);
317 }
318 }
319}
320
321/* --------------------------------------------------------------------------
322 Create diva PCI adapter and init internal adapter structures
323 -------------------------------------------------------------------------- */
324static void *divas_create_pci_card(int handle, void *pci_dev_handle)
325{
326 diva_supported_cards_info_t *pI = &divas_supported_cards[handle];
327 diva_os_spin_lock_magic_t old_irql;
328 diva_os_xdi_adapter_t *a;
329
330 DBG_LOG(("found %d-%s", pI->CardOrdinal, CardProperties[pI->CardOrdinal].Name))
331
332 if (!(a = (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) {
333 DBG_ERR(("A: can't alloc adapter"));
334 return NULL;
335 }
336
337 memset(a, 0x00, sizeof(*a));
338
339 a->CardIndex = handle;
340 a->CardOrdinal = pI->CardOrdinal;
341 a->Bus = DIVAS_XDI_ADAPTER_BUS_PCI;
342 a->xdi_adapter.cardType = a->CardOrdinal;
343 a->resources.pci.bus = diva_os_get_pci_bus(pci_dev_handle);
344 a->resources.pci.func = diva_os_get_pci_func(pci_dev_handle);
345 a->resources.pci.hdev = pci_dev_handle;
346
347 /*
348 Add master adapter first, so slave adapters will receive higher
349 numbers as master adapter
350 */
351 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
352 list_add_tail(&a->link, &adapter_queue);
353 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
354
355 if ((*(pI->init_card)) (a)) {
356 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
357 list_del(&a->link);
358 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
359 diva_os_free(0, a);
360 DBG_ERR(("A: can't get adapter resources"));
361 return NULL;
362 }
363
364 return (a);
365}
366
367/* --------------------------------------------------------------------------
368 Called on driver unload FINIT, finit, Unload
369 -------------------------------------------------------------------------- */
370void divasa_xdi_driver_unload(void)
371{
372 diva_os_xdi_adapter_t *a;
373
374 while ((a = get_and_remove_from_queue())) {
375 if (a->interface.cleanup_adapter_proc) {
376 (*(a->interface.cleanup_adapter_proc)) (a);
377 }
378 if (a->controller) {
379 IoAdapters[a->controller - 1] = NULL;
380 remove_adapter_proc(a);
381 }
382 diva_os_free(0, a);
383 }
384 diva_os_destroy_spin_lock(&adapter_lock, "adapter");
385}
386
387/*
388** Receive and process command from user mode utility
389*/
390void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
391 int length, void *mptr,
392 divas_xdi_copy_from_user_fn_t cp_fn)
393{
394 diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
395 diva_os_xdi_adapter_t *a = NULL;
396 diva_os_spin_lock_magic_t old_irql;
397 struct list_head *tmp;
398
399 if (length < sizeof(diva_xdi_um_cfg_cmd_t)) {
400 DBG_ERR(("A: A(?) open, msg too small (%d < %d)",
401 length, sizeof(diva_xdi_um_cfg_cmd_t)))
402 return NULL;
403 }
404 if ((*cp_fn) (os_handle, msg, src, sizeof(*msg)) <= 0) {
405 DBG_ERR(("A: A(?) open, write error"))
406 return NULL;
407 }
408 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter");
409 list_for_each(tmp, &adapter_queue) {
410 a = list_entry(tmp, diva_os_xdi_adapter_t, link);
411 if (a->controller == (int)msg->adapter)
412 break;
413 a = NULL;
414 }
415 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "open_adapter");
416
417 if (!a) {
418 DBG_ERR(("A: A(%d) open, adapter not found", msg->adapter))
419 }
420
421 return (a);
422}
423
424/*
425** Easy cleanup mailbox status
426*/
427void diva_xdi_close_adapter(void *adapter, void *os_handle)
428{
429 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
430
431 a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
432 if (a->xdi_mbox.data) {
433 diva_os_free(0, a->xdi_mbox.data);
434 a->xdi_mbox.data = NULL;
435 }
436}
437
438int
439diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
440 int length, void *mptr,
441 divas_xdi_copy_from_user_fn_t cp_fn)
442{
443 diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
444 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
445 void *data;
446
447 if (a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY) {
448 DBG_ERR(("A: A(%d) write, mbox busy", a->controller))
449 return (-1);
450 }
451
452 if (length < sizeof(diva_xdi_um_cfg_cmd_t)) {
453 DBG_ERR(("A: A(%d) write, message too small (%d < %d)",
454 a->controller, length,
455 sizeof(diva_xdi_um_cfg_cmd_t)))
456 return (-3);
457 }
458
459 if (!(data = diva_os_malloc(0, length))) {
460 DBG_ERR(("A: A(%d) write, ENOMEM", a->controller))
461 return (-2);
462 }
463
464 if (msg) {
465 *(diva_xdi_um_cfg_cmd_t *)data = *msg;
466 length = (*cp_fn) (os_handle, (char *)data + sizeof(*msg),
467 src + sizeof(*msg), length - sizeof(*msg));
468 } else {
469 length = (*cp_fn) (os_handle, data, src, length);
470 }
471 if (length > 0) {
472 if ((*(a->interface.cmd_proc))
473 (a, (diva_xdi_um_cfg_cmd_t *) data, length)) {
474 length = -3;
475 }
476 } else {
477 DBG_ERR(("A: A(%d) write error (%d)", a->controller,
478 length))
479 }
480
481 diva_os_free(0, data);
482
483 return (length);
484}
485
486/*
487** Write answers to user mode utility, if any
488*/
489int
490diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
491 int max_length, divas_xdi_copy_to_user_fn_t cp_fn)
492{
493 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
494 int ret;
495
496 if (!(a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY)) {
497 DBG_ERR(("A: A(%d) rx mbox empty", a->controller))
498 return (-1);
499 }
500 if (!a->xdi_mbox.data) {
501 a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
502 DBG_ERR(("A: A(%d) rx ENOMEM", a->controller))
503 return (-2);
504 }
505
506 if (max_length < a->xdi_mbox.data_length) {
507 DBG_ERR(("A: A(%d) rx buffer too short(%d < %d)",
508 a->controller, max_length,
509 a->xdi_mbox.data_length))
510 return (-3);
511 }
512
513 ret = (*cp_fn) (os_handle, dst, a->xdi_mbox.data,
514 a->xdi_mbox.data_length);
515 if (ret > 0) {
516 diva_os_free(0, a->xdi_mbox.data);
517 a->xdi_mbox.data = NULL;
518 a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
519 }
520
521 return (ret);
522}
523
524
525irqreturn_t diva_os_irq_wrapper(int irq, void *context)
526{
527 diva_os_xdi_adapter_t *a = context;
528 diva_xdi_clear_interrupts_proc_t clear_int_proc;
529
530 if (!a || !a->xdi_adapter.diva_isr_handler)
531 return IRQ_NONE;
532
533 if ((clear_int_proc = a->clear_interrupts_proc)) {
534 (*clear_int_proc) (a);
535 a->clear_interrupts_proc = NULL;
536 return IRQ_HANDLED;
537 }
538
539 (*(a->xdi_adapter.diva_isr_handler)) (&a->xdi_adapter);
540 return IRQ_HANDLED;
541}
542
543static void diva_init_request_array(void)
544{
545 Requests[0] = DivaIdiRequest0;
546 Requests[1] = DivaIdiRequest1;
547 Requests[2] = DivaIdiRequest2;
548 Requests[3] = DivaIdiRequest3;
549 Requests[4] = DivaIdiRequest4;
550 Requests[5] = DivaIdiRequest5;
551 Requests[6] = DivaIdiRequest6;
552 Requests[7] = DivaIdiRequest7;
553 Requests[8] = DivaIdiRequest8;
554 Requests[9] = DivaIdiRequest9;
555 Requests[10] = DivaIdiRequest10;
556 Requests[11] = DivaIdiRequest11;
557 Requests[12] = DivaIdiRequest12;
558 Requests[13] = DivaIdiRequest13;
559 Requests[14] = DivaIdiRequest14;
560 Requests[15] = DivaIdiRequest15;
561 Requests[16] = DivaIdiRequest16;
562 Requests[17] = DivaIdiRequest17;
563 Requests[18] = DivaIdiRequest18;
564 Requests[19] = DivaIdiRequest19;
565 Requests[20] = DivaIdiRequest20;
566 Requests[21] = DivaIdiRequest21;
567 Requests[22] = DivaIdiRequest22;
568 Requests[23] = DivaIdiRequest23;
569 Requests[24] = DivaIdiRequest24;
570 Requests[25] = DivaIdiRequest25;
571 Requests[26] = DivaIdiRequest26;
572 Requests[27] = DivaIdiRequest27;
573 Requests[28] = DivaIdiRequest28;
574 Requests[29] = DivaIdiRequest29;
575 Requests[30] = DivaIdiRequest30;
576 Requests[31] = DivaIdiRequest31;
577}
578
579void diva_xdi_display_adapter_features(int card)
580{
581 dword features;
582 if (!card || ((card - 1) >= MAX_ADAPTER) || !IoAdapters[card - 1]) {
583 return;
584 }
585 card--;
586 features = IoAdapters[card]->Properties.Features;
587
588 DBG_LOG(("FEATURES FOR ADAPTER: %d", card + 1))
589 DBG_LOG((" DI_FAX3 : %s",
590 (features & DI_FAX3) ? "Y" : "N"))
591 DBG_LOG((" DI_MODEM : %s",
592 (features & DI_MODEM) ? "Y" : "N"))
593 DBG_LOG((" DI_POST : %s",
594 (features & DI_POST) ? "Y" : "N"))
595 DBG_LOG((" DI_V110 : %s",
596 (features & DI_V110) ? "Y" : "N"))
597 DBG_LOG((" DI_V120 : %s",
598 (features & DI_V120) ? "Y" : "N"))
599 DBG_LOG((" DI_POTS : %s",
600 (features & DI_POTS) ? "Y" : "N"))
601 DBG_LOG((" DI_CODEC : %s",
602 (features & DI_CODEC) ? "Y" : "N"))
603 DBG_LOG((" DI_MANAGE : %s",
604 (features & DI_MANAGE) ? "Y" : "N"))
605 DBG_LOG((" DI_V_42 : %s",
606 (features & DI_V_42) ? "Y" : "N"))
607 DBG_LOG((" DI_EXTD_FAX : %s",
608 (features & DI_EXTD_FAX) ? "Y" : "N"))
609 DBG_LOG((" DI_AT_PARSER : %s",
610 (features & DI_AT_PARSER) ? "Y" : "N"))
611 DBG_LOG((" DI_VOICE_OVER_IP : %s",
612 (features & DI_VOICE_OVER_IP) ? "Y" : "N"))
613 }
614
615void diva_add_slave_adapter(diva_os_xdi_adapter_t *a)
616{
617 diva_os_spin_lock_magic_t old_irql;
618
619 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add_slave");
620 list_add_tail(&a->link, &adapter_queue);
621 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add_slave");
622}
623
624int diva_card_read_xlog(diva_os_xdi_adapter_t *a)
625{
626 diva_get_xlog_t *req;
627 byte *data;
628
629 if (!a->xdi_adapter.Initialized || !a->xdi_adapter.DIRequest) {
630 return (-1);
631 }
632 if (!(data = diva_os_malloc(0, sizeof(struct mi_pc_maint)))) {
633 return (-1);
634 }
635 memset(data, 0x00, sizeof(struct mi_pc_maint));
636
637 if (!(req = diva_os_malloc(0, sizeof(*req)))) {
638 diva_os_free(0, data);
639 return (-1);
640 }
641 req->command = 0x0400;
642 req->req = LOG;
643 req->rc = 0x00;
644
645 (*(a->xdi_adapter.DIRequest)) (&a->xdi_adapter, (ENTITY *) req);
646
647 if (!req->rc || req->req) {
648 diva_os_free(0, data);
649 diva_os_free(0, req);
650 return (-1);
651 }
652
653 memcpy(data, &req->req, sizeof(struct mi_pc_maint));
654
655 diva_os_free(0, req);
656
657 a->xdi_mbox.data_length = sizeof(struct mi_pc_maint);
658 a->xdi_mbox.data = data;
659 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
660
661 return (0);
662}
663
664void xdiFreeFile(void *handle)
665{
666}
diff --git a/drivers/isdn/hardware/eicon/diva.h b/drivers/isdn/hardware/eicon/diva.h
deleted file mode 100644
index 1ad76650fbf9..000000000000
--- a/drivers/isdn/hardware/eicon/diva.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: diva.h,v 1.1.2.2 2001/02/08 12:25:43 armin Exp $ */
3
4#ifndef __DIVA_XDI_OS_PART_H__
5#define __DIVA_XDI_OS_PART_H__
6
7
8int divasa_xdi_driver_entry(void);
9void divasa_xdi_driver_unload(void);
10void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal);
11void diva_driver_remove_card(void *pdiva);
12
13typedef int (*divas_xdi_copy_to_user_fn_t) (void *os_handle, void __user *dst,
14 const void *src, int length);
15
16typedef int (*divas_xdi_copy_from_user_fn_t) (void *os_handle, void *dst,
17 const void __user *src, int length);
18
19int diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
20 int max_length, divas_xdi_copy_to_user_fn_t cp_fn);
21
22int diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
23 int length, void *msg,
24 divas_xdi_copy_from_user_fn_t cp_fn);
25
26void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
27 int length, void *msg,
28 divas_xdi_copy_from_user_fn_t cp_fn);
29
30void diva_xdi_close_adapter(void *adapter, void *os_handle);
31
32
33#endif
diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
deleted file mode 100644
index 60e79257dd5f..000000000000
--- a/drivers/isdn/hardware/eicon/diva_didd.c
+++ /dev/null
@@ -1,139 +0,0 @@
1/* $Id: diva_didd.c,v 1.13.6.4 2005/02/11 19:40:25 armin Exp $
2 *
3 * DIDD Interface module for Eicon active cards.
4 *
5 * Functions are in dadapter.c
6 *
7 * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
8 * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
9 *
10 * This software may be used and distributed according to the terms
11 * of the GNU General Public License, incorporated herein by reference.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/proc_fs.h>
18#include <linux/seq_file.h>
19#include <net/net_namespace.h>
20
21#include "platform.h"
22#include "di_defs.h"
23#include "dadapter.h"
24#include "divasync.h"
25#include "did_vers.h"
26
27static char *main_revision = "$Revision: 1.13.6.4 $";
28
29static char *DRIVERNAME =
30 "Eicon DIVA - DIDD table (http://www.melware.net)";
31static char *DRIVERLNAME = "divadidd";
32char *DRIVERRELEASE_DIDD = "2.0";
33
34MODULE_DESCRIPTION("DIDD table driver for diva drivers");
35MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
36MODULE_SUPPORTED_DEVICE("Eicon diva drivers");
37MODULE_LICENSE("GPL");
38
39#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
40#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
41
42extern int diddfunc_init(void);
43extern void diddfunc_finit(void);
44
45extern void DIVA_DIDD_Read(void *, int);
46
47static struct proc_dir_entry *proc_didd;
48struct proc_dir_entry *proc_net_eicon = NULL;
49
50EXPORT_SYMBOL(DIVA_DIDD_Read);
51EXPORT_SYMBOL(proc_net_eicon);
52
53static char *getrev(const char *revision)
54{
55 char *rev;
56 char *p;
57 if ((p = strchr(revision, ':'))) {
58 rev = p + 2;
59 p = strchr(rev, '$');
60 *--p = 0;
61 } else
62 rev = "1.0";
63 return rev;
64}
65
66static int divadidd_proc_show(struct seq_file *m, void *v)
67{
68 char tmprev[32];
69
70 strcpy(tmprev, main_revision);
71 seq_printf(m, "%s\n", DRIVERNAME);
72 seq_printf(m, "name : %s\n", DRIVERLNAME);
73 seq_printf(m, "release : %s\n", DRIVERRELEASE_DIDD);
74 seq_printf(m, "build : %s(%s)\n",
75 diva_didd_common_code_build, DIVA_BUILD);
76 seq_printf(m, "revision : %s\n", getrev(tmprev));
77
78 return 0;
79}
80
81static int __init create_proc(void)
82{
83 proc_net_eicon = proc_mkdir("eicon", init_net.proc_net);
84
85 if (proc_net_eicon) {
86 proc_didd = proc_create_single(DRIVERLNAME, S_IRUGO,
87 proc_net_eicon, divadidd_proc_show);
88 return (1);
89 }
90 return (0);
91}
92
93static void remove_proc(void)
94{
95 remove_proc_entry(DRIVERLNAME, proc_net_eicon);
96 remove_proc_entry("eicon", init_net.proc_net);
97}
98
99static int __init divadidd_init(void)
100{
101 char tmprev[32];
102 int ret = 0;
103
104 printk(KERN_INFO "%s\n", DRIVERNAME);
105 printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_DIDD);
106 strcpy(tmprev, main_revision);
107 printk("%s Build:%s(%s)\n", getrev(tmprev),
108 diva_didd_common_code_build, DIVA_BUILD);
109
110 if (!create_proc()) {
111 printk(KERN_ERR "%s: could not create proc entry\n",
112 DRIVERLNAME);
113 ret = -EIO;
114 goto out;
115 }
116
117 if (!diddfunc_init()) {
118 printk(KERN_ERR "%s: failed to connect to DIDD.\n",
119 DRIVERLNAME);
120#ifdef MODULE
121 remove_proc();
122#endif
123 ret = -EIO;
124 goto out;
125 }
126
127out:
128 return (ret);
129}
130
131static void __exit divadidd_exit(void)
132{
133 diddfunc_finit();
134 remove_proc();
135 printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
136}
137
138module_init(divadidd_init);
139module_exit(divadidd_exit);
diff --git a/drivers/isdn/hardware/eicon/diva_dma.c b/drivers/isdn/hardware/eicon/diva_dma.c
deleted file mode 100644
index 217b6aa9f612..000000000000
--- a/drivers/isdn/hardware/eicon/diva_dma.c
+++ /dev/null
@@ -1,94 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include "platform.h"
27#include "diva_dma.h"
28/*
29 Every entry has length of PAGE_SIZE
30 and represents one single physical page
31*/
32struct _diva_dma_map_entry {
33 int busy;
34 dword phys_bus_addr; /* 32bit address as seen by the card */
35 void *local_ram_addr; /* local address as seen by the host */
36 void *addr_handle; /* handle uset to free allocated memory */
37};
38/*
39 Create local mapping structure and init it to default state
40*/
41struct _diva_dma_map_entry *diva_alloc_dma_map(void *os_context, int nentries) {
42 diva_dma_map_entry_t *pmap = diva_os_malloc(0, sizeof(*pmap) * (nentries + 1));
43 if (pmap)
44 memset(pmap, 0, sizeof(*pmap) * (nentries + 1));
45 return pmap;
46}
47/*
48 Free local map (context should be freed before) if any
49*/
50void diva_free_dma_mapping(struct _diva_dma_map_entry *pmap) {
51 if (pmap) {
52 diva_os_free(0, pmap);
53 }
54}
55/*
56 Set information saved on the map entry
57*/
58void diva_init_dma_map_entry(struct _diva_dma_map_entry *pmap,
59 int nr, void *virt, dword phys,
60 void *addr_handle) {
61 pmap[nr].phys_bus_addr = phys;
62 pmap[nr].local_ram_addr = virt;
63 pmap[nr].addr_handle = addr_handle;
64}
65/*
66 Allocate one single entry in the map
67*/
68int diva_alloc_dma_map_entry(struct _diva_dma_map_entry *pmap) {
69 int i;
70 for (i = 0; (pmap && pmap[i].local_ram_addr); i++) {
71 if (!pmap[i].busy) {
72 pmap[i].busy = 1;
73 return (i);
74 }
75 }
76 return (-1);
77}
78/*
79 Free one single entry in the map
80*/
81void diva_free_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr) {
82 pmap[nr].busy = 0;
83}
84/*
85 Get information saved on the map entry
86*/
87void diva_get_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr,
88 void **pvirt, dword *pphys) {
89 *pphys = pmap[nr].phys_bus_addr;
90 *pvirt = pmap[nr].local_ram_addr;
91}
92void *diva_get_entry_handle(struct _diva_dma_map_entry *pmap, int nr) {
93 return (pmap[nr].addr_handle);
94}
diff --git a/drivers/isdn/hardware/eicon/diva_dma.h b/drivers/isdn/hardware/eicon/diva_dma.h
deleted file mode 100644
index d32c91be562b..000000000000
--- a/drivers/isdn/hardware/eicon/diva_dma.h
+++ /dev/null
@@ -1,48 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_DMA_MAPPING_IFC_H__
27#define __DIVA_DMA_MAPPING_IFC_H__
28typedef struct _diva_dma_map_entry diva_dma_map_entry_t;
29struct _diva_dma_map_entry *diva_alloc_dma_map(void *os_context, int nentries);
30void diva_init_dma_map_entry(struct _diva_dma_map_entry *pmap,
31 int nr, void *virt, dword phys,
32 void *addr_handle);
33int diva_alloc_dma_map_entry(struct _diva_dma_map_entry *pmap);
34void diva_free_dma_map_entry(struct _diva_dma_map_entry *pmap, int entry);
35void diva_get_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr,
36 void **pvirt, dword *pphys);
37void diva_free_dma_mapping(struct _diva_dma_map_entry *pmap);
38/*
39 Functionality to be implemented by OS wrapper
40 and running in process context
41*/
42void diva_init_dma_map(void *hdev,
43 struct _diva_dma_map_entry **ppmap,
44 int nentries);
45void diva_free_dma_map(void *hdev,
46 struct _diva_dma_map_entry *pmap);
47void *diva_get_entry_handle(struct _diva_dma_map_entry *pmap, int nr);
48#endif
diff --git a/drivers/isdn/hardware/eicon/diva_pci.h b/drivers/isdn/hardware/eicon/diva_pci.h
deleted file mode 100644
index 7ef5db98ad3c..000000000000
--- a/drivers/isdn/hardware/eicon/diva_pci.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: diva_pci.h,v 1.6 2003/01/04 15:29:45 schindler Exp $ */
3
4#ifndef __DIVA_PCI_INTERFACE_H__
5#define __DIVA_PCI_INTERFACE_H__
6
7void __iomem *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a,
8 int id,
9 unsigned long bar,
10 unsigned long area_length);
11void divasa_unmap_pci_bar(void __iomem *bar);
12unsigned long divasa_get_pci_irq(unsigned char bus,
13 unsigned char func, void *pci_dev_handle);
14unsigned long divasa_get_pci_bar(unsigned char bus,
15 unsigned char func,
16 int bar, void *pci_dev_handle);
17byte diva_os_get_pci_bus(void *pci_dev_handle);
18byte diva_os_get_pci_func(void *pci_dev_handle);
19
20#endif
diff --git a/drivers/isdn/hardware/eicon/divacapi.h b/drivers/isdn/hardware/eicon/divacapi.h
deleted file mode 100644
index c4868a0d82f4..000000000000
--- a/drivers/isdn/hardware/eicon/divacapi.h
+++ /dev/null
@@ -1,1350 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26
27/*#define DEBUG */
28
29#include <linux/types.h>
30
31#define IMPLEMENT_DTMF 1
32#define IMPLEMENT_LINE_INTERCONNECT2 1
33#define IMPLEMENT_ECHO_CANCELLER 1
34#define IMPLEMENT_RTP 1
35#define IMPLEMENT_T38 1
36#define IMPLEMENT_FAX_SUB_SEP_PWD 1
37#define IMPLEMENT_V18 1
38#define IMPLEMENT_DTMF_TONE 1
39#define IMPLEMENT_PIAFS 1
40#define IMPLEMENT_FAX_PAPER_FORMATS 1
41#define IMPLEMENT_VOWN 1
42#define IMPLEMENT_CAPIDTMF 1
43#define IMPLEMENT_FAX_NONSTANDARD 1
44#define VSWITCH_SUPPORT 1
45
46
47#define IMPLEMENT_LINE_INTERCONNECT 0
48#define IMPLEMENT_MARKED_OK_AFTER_FC 1
49
50#include "capidtmf.h"
51
52/*------------------------------------------------------------------*/
53/* Common API internal definitions */
54/*------------------------------------------------------------------*/
55
56#define MAX_APPL 240
57#define MAX_NCCI 127
58
59#define MSG_IN_QUEUE_SIZE ((4096 + 3) & 0xfffc) /* must be multiple of 4 */
60
61
62#define MSG_IN_OVERHEAD sizeof(APPL *)
63
64#define MAX_NL_CHANNEL 255
65#define MAX_DATA_B3 8
66#define MAX_DATA_ACK MAX_DATA_B3
67#define MAX_MULTI_IE 6
68#define MAX_MSG_SIZE 256
69#define MAX_MSG_PARMS 10
70#define MAX_CPN_MASK_SIZE 16
71#define MAX_MSN_CONFIG 10
72#define EXT_CONTROLLER 0x80
73#define CODEC 0x01
74#define CODEC_PERMANENT 0x02
75#define ADV_VOICE 0x03
76#define MAX_CIP_TYPES 5 /* kind of CIP types for group optimization */
77
78#define FAX_CONNECT_INFO_BUFFER_SIZE 256
79#define NCPI_BUFFER_SIZE 256
80
81#define MAX_CHANNELS_PER_PLCI 8
82#define MAX_INTERNAL_COMMAND_LEVELS 4
83#define INTERNAL_REQ_BUFFER_SIZE 272
84
85#define INTERNAL_IND_BUFFER_SIZE 768
86
87#define DTMF_PARAMETER_BUFFER_SIZE 12
88#define ADV_VOICE_COEF_BUFFER_SIZE 50
89
90#define LI_PLCI_B_QUEUE_ENTRIES 256
91
92
93
94typedef struct _APPL APPL;
95typedef struct _PLCI PLCI;
96typedef struct _NCCI NCCI;
97typedef struct _DIVA_CAPI_ADAPTER DIVA_CAPI_ADAPTER;
98typedef struct _DATA_B3_DESC DATA_B3_DESC;
99typedef struct _DATA_ACK_DESC DATA_ACK_DESC;
100typedef struct manufacturer_profile_s MANUFACTURER_PROFILE;
101typedef struct fax_ncpi_s FAX_NCPI;
102typedef struct api_parse_s API_PARSE;
103typedef struct api_save_s API_SAVE;
104typedef struct msn_config_s MSN_CONFIG;
105typedef struct msn_config_max_s MSN_CONFIG_MAX;
106typedef struct msn_ld_s MSN_LD;
107
108struct manufacturer_profile_s {
109 dword private_options;
110 dword rtp_primary_payloads;
111 dword rtp_additional_payloads;
112};
113
114struct fax_ncpi_s {
115 word options;
116 word format;
117};
118
119struct msn_config_s {
120 byte msn[MAX_CPN_MASK_SIZE];
121};
122
123struct msn_config_max_s {
124 MSN_CONFIG msn_conf[MAX_MSN_CONFIG];
125};
126
127struct msn_ld_s {
128 dword low;
129 dword high;
130};
131
132struct api_parse_s {
133 word length;
134 byte *info;
135};
136
137struct api_save_s {
138 API_PARSE parms[MAX_MSG_PARMS + 1];
139 byte info[MAX_MSG_SIZE];
140};
141
142struct _DATA_B3_DESC {
143 word Handle;
144 word Number;
145 word Flags;
146 word Length;
147 void *P;
148};
149
150struct _DATA_ACK_DESC {
151 word Handle;
152 word Number;
153};
154
155typedef void (*t_std_internal_command)(dword Id, PLCI *plci, byte Rc);
156
157/************************************************************************/
158/* Don't forget to adapt dos.asm after changing the _APPL structure!!!! */
159struct _APPL {
160 word Id;
161 word NullCREnable;
162 word CDEnable;
163 dword S_Handle;
164
165
166
167
168
169
170 LIST_ENTRY s_function;
171 dword s_context;
172 word s_count;
173 APPL *s_next;
174 byte *xbuffer_used;
175 void **xbuffer_internal;
176 void **xbuffer_ptr;
177
178
179
180
181
182
183 byte *queue;
184 word queue_size;
185 word queue_free;
186 word queue_read;
187 word queue_write;
188 word queue_signal;
189 byte msg_lost;
190 byte appl_flags;
191 word Number;
192
193 word MaxBuffer;
194 byte MaxNCCI;
195 byte MaxNCCIData;
196 word MaxDataLength;
197 word NCCIDataFlowCtrlTimer;
198 byte *ReceiveBuffer;
199 word *DataNCCI;
200 word *DataFlags;
201};
202
203
204struct _PLCI {
205 ENTITY Sig;
206 ENTITY NL;
207 word RNum;
208 word RFlags;
209 BUFFERS RData[2];
210 BUFFERS XData[1];
211 BUFFERS NData[2];
212
213 DIVA_CAPI_ADAPTER *adapter;
214 APPL *appl;
215 PLCI *relatedPTYPLCI;
216 byte Id;
217 byte State;
218 byte sig_req;
219 byte nl_req;
220 byte SuppState;
221 byte channels;
222 byte tel;
223 byte B1_resource;
224 byte B2_prot;
225 byte B3_prot;
226
227 word command;
228 word m_command;
229 word internal_command;
230 word number;
231 word req_in_start;
232 word req_in;
233 word req_out;
234 word msg_in_write_pos;
235 word msg_in_read_pos;
236 word msg_in_wrap_pos;
237
238 void *data_sent_ptr;
239 byte data_sent;
240 byte send_disc;
241 byte sig_global_req;
242 byte sig_remove_id;
243 byte nl_global_req;
244 byte nl_remove_id;
245 byte b_channel;
246 byte adv_nl;
247 byte manufacturer;
248 byte call_dir;
249 byte hook_state;
250 byte spoofed_msg;
251 byte ptyState;
252 byte cr_enquiry;
253 word hangup_flow_ctrl_timer;
254
255 word ncci_ring_list;
256 byte inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI];
257 t_std_internal_command internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS];
258 DECLARE_BITMAP(c_ind_mask_table, MAX_APPL);
259 DECLARE_BITMAP(group_optimization_mask_table, MAX_APPL);
260 byte RBuffer[200];
261 dword msg_in_queue[MSG_IN_QUEUE_SIZE/sizeof(dword)];
262 API_SAVE saved_msg;
263 API_SAVE B_protocol;
264 byte fax_connect_info_length;
265 byte fax_connect_info_buffer[FAX_CONNECT_INFO_BUFFER_SIZE];
266 byte fax_edata_ack_length;
267 word nsf_control_bits;
268 byte ncpi_state;
269 byte ncpi_buffer[NCPI_BUFFER_SIZE];
270
271 byte internal_req_buffer[INTERNAL_REQ_BUFFER_SIZE];
272 byte internal_ind_buffer[INTERNAL_IND_BUFFER_SIZE + 3];
273 dword requested_options_conn;
274 dword requested_options;
275 word B1_facilities;
276 API_SAVE *adjust_b_parms_msg;
277 word adjust_b_facilities;
278 word adjust_b_command;
279 word adjust_b_ncci;
280 word adjust_b_mode;
281 word adjust_b_state;
282 byte adjust_b_restore;
283
284 byte dtmf_rec_active;
285 word dtmf_rec_pulse_ms;
286 word dtmf_rec_pause_ms;
287 byte dtmf_send_requests;
288 word dtmf_send_pulse_ms;
289 word dtmf_send_pause_ms;
290 word dtmf_cmd;
291 word dtmf_msg_number_queue[8];
292 byte dtmf_parameter_length;
293 byte dtmf_parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE];
294
295
296 t_capidtmf_state capidtmf_state;
297
298
299 byte li_bchannel_id; /* BRI: 1..2, PRI: 1..32 */
300 byte li_channel_bits;
301 byte li_notify_update;
302 word li_cmd;
303 word li_write_command;
304 word li_write_channel;
305 word li_plci_b_write_pos;
306 word li_plci_b_read_pos;
307 word li_plci_b_req_pos;
308 dword li_plci_b_queue[LI_PLCI_B_QUEUE_ENTRIES];
309
310
311 word ec_cmd;
312 word ec_idi_options;
313 word ec_tail_length;
314
315
316 byte tone_last_indication_code;
317
318 byte vswitchstate;
319 byte vsprot;
320 byte vsprotdialect;
321 byte notifiedcall; /* Flag if it is a spoofed call */
322
323 int rx_dma_descriptor;
324 dword rx_dma_magic;
325};
326
327
328struct _NCCI {
329 byte data_out;
330 byte data_pending;
331 byte data_ack_out;
332 byte data_ack_pending;
333 DATA_B3_DESC DBuffer[MAX_DATA_B3];
334 DATA_ACK_DESC DataAck[MAX_DATA_ACK];
335};
336
337
338struct _DIVA_CAPI_ADAPTER {
339 IDI_CALL request;
340 byte Id;
341 byte max_plci;
342 byte max_listen;
343 byte listen_active;
344 PLCI *plci;
345 byte ch_ncci[MAX_NL_CHANNEL + 1];
346 byte ncci_ch[MAX_NCCI + 1];
347 byte ncci_plci[MAX_NCCI + 1];
348 byte ncci_state[MAX_NCCI + 1];
349 byte ncci_next[MAX_NCCI + 1];
350 NCCI ncci[MAX_NCCI + 1];
351
352 byte ch_flow_control[MAX_NL_CHANNEL + 1]; /* Used by XON protocol */
353 byte ch_flow_control_pending;
354 byte ch_flow_plci[MAX_NL_CHANNEL + 1];
355 int last_flow_control_ch;
356
357 dword Info_Mask[MAX_APPL];
358 dword CIP_Mask[MAX_APPL];
359
360 dword Notification_Mask[MAX_APPL];
361 PLCI *codec_listen[MAX_APPL];
362 dword requested_options_table[MAX_APPL];
363 API_PROFILE profile;
364 MANUFACTURER_PROFILE man_profile;
365 dword manufacturer_features;
366
367 byte AdvCodecFLAG;
368 PLCI *AdvCodecPLCI;
369 PLCI *AdvSignalPLCI;
370 APPL *AdvSignalAppl;
371 byte TelOAD[23];
372 byte TelOSA[23];
373 byte scom_appl_disable;
374 PLCI *automatic_lawPLCI;
375 byte automatic_law;
376 byte u_law;
377
378 byte adv_voice_coef_length;
379 byte adv_voice_coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE];
380
381 byte li_pri;
382 byte li_channels;
383 word li_base;
384
385 byte adapter_disabled;
386 byte group_optimization_enabled; /* use application groups if enabled */
387 dword sdram_bar;
388 byte flag_dynamic_l1_down; /* for hunt groups:down layer 1 if no appl present*/
389 byte FlowControlIdTable[256];
390 byte FlowControlSkipTable[256];
391 void *os_card; /* pointer to associated OS dependent adapter structure */
392};
393
394
395/*------------------------------------------------------------------*/
396/* Application flags */
397/*------------------------------------------------------------------*/
398
399#define APPL_FLAG_OLD_LI_SPEC 0x01
400#define APPL_FLAG_PRIV_EC_SPEC 0x02
401
402
403/*------------------------------------------------------------------*/
404/* API parameter definitions */
405/*------------------------------------------------------------------*/
406
407#define X75_TTX 1 /* x.75 for ttx */
408#define TRF 2 /* transparent with hdlc framing */
409#define TRF_IN 3 /* transparent with hdlc fr. inc. */
410#define SDLC 4 /* sdlc, sna layer-2 */
411#define X75_BTX 5 /* x.75 for btx */
412#define LAPD 6 /* lapd (Q.921) */
413#define X25_L2 7 /* x.25 layer-2 */
414#define V120_L2 8 /* V.120 layer-2 protocol */
415#define V42_IN 9 /* V.42 layer-2 protocol, incoming */
416#define V42 10 /* V.42 layer-2 protocol */
417#define MDM_ATP 11 /* AT Parser built in the L2 */
418#define X75_V42BIS 12 /* ISO7776 (X.75 SLP) modified to support V.42 bis compression */
419#define RTPL2_IN 13 /* RTP layer-2 protocol, incoming */
420#define RTPL2 14 /* RTP layer-2 protocol */
421#define V120_V42BIS 15 /* V.120 layer-2 protocol supporting V.42 bis compression */
422
423#define T70NL 1
424#define X25PLP 2
425#define T70NLX 3
426#define TRANSPARENT_NL 4
427#define ISO8208 5
428#define T30 6
429
430
431/*------------------------------------------------------------------*/
432/* FAX interface to IDI */
433/*------------------------------------------------------------------*/
434
435#define CAPI_MAX_HEAD_LINE_SPACE 89
436#define CAPI_MAX_DATE_TIME_LENGTH 18
437
438#define T30_MAX_STATION_ID_LENGTH 20
439#define T30_MAX_SUBADDRESS_LENGTH 20
440#define T30_MAX_PASSWORD_LENGTH 20
441
442typedef struct t30_info_s T30_INFO;
443struct t30_info_s {
444 byte code;
445 byte rate_div_2400;
446 byte resolution;
447 byte data_format;
448 byte pages_low;
449 byte pages_high;
450 byte operating_mode;
451 byte control_bits_low;
452 byte control_bits_high;
453 byte feature_bits_low;
454 byte feature_bits_high;
455 byte recording_properties;
456 byte universal_6;
457 byte universal_7;
458 byte station_id_len;
459 byte head_line_len;
460 byte station_id[T30_MAX_STATION_ID_LENGTH];
461/* byte head_line[]; */
462/* byte sub_sep_length; */
463/* byte sub_sep_field[]; */
464/* byte pwd_length; */
465/* byte pwd_field[]; */
466/* byte nsf_info_length; */
467/* byte nsf_info_field[]; */
468};
469
470
471#define T30_RESOLUTION_R8_0385 0x00
472#define T30_RESOLUTION_R8_0770_OR_200 0x01
473#define T30_RESOLUTION_R8_1540 0x02
474#define T30_RESOLUTION_R16_1540_OR_400 0x04
475#define T30_RESOLUTION_R4_0385_OR_100 0x08
476#define T30_RESOLUTION_300_300 0x10
477#define T30_RESOLUTION_INCH_BASED 0x40
478#define T30_RESOLUTION_METRIC_BASED 0x80
479
480#define T30_RECORDING_WIDTH_ISO_A4 0
481#define T30_RECORDING_WIDTH_ISO_B4 1
482#define T30_RECORDING_WIDTH_ISO_A3 2
483#define T30_RECORDING_WIDTH_COUNT 3
484
485#define T30_RECORDING_LENGTH_ISO_A4 0
486#define T30_RECORDING_LENGTH_ISO_B4 1
487#define T30_RECORDING_LENGTH_UNLIMITED 2
488#define T30_RECORDING_LENGTH_COUNT 3
489
490#define T30_MIN_SCANLINE_TIME_00_00_00 0
491#define T30_MIN_SCANLINE_TIME_05_05_05 1
492#define T30_MIN_SCANLINE_TIME_10_05_05 2
493#define T30_MIN_SCANLINE_TIME_10_10_10 3
494#define T30_MIN_SCANLINE_TIME_20_10_10 4
495#define T30_MIN_SCANLINE_TIME_20_20_20 5
496#define T30_MIN_SCANLINE_TIME_40_20_20 6
497#define T30_MIN_SCANLINE_TIME_40_40_40 7
498#define T30_MIN_SCANLINE_TIME_RES_8 8
499#define T30_MIN_SCANLINE_TIME_RES_9 9
500#define T30_MIN_SCANLINE_TIME_RES_10 10
501#define T30_MIN_SCANLINE_TIME_10_10_05 11
502#define T30_MIN_SCANLINE_TIME_20_10_05 12
503#define T30_MIN_SCANLINE_TIME_20_20_10 13
504#define T30_MIN_SCANLINE_TIME_40_20_10 14
505#define T30_MIN_SCANLINE_TIME_40_40_20 15
506#define T30_MIN_SCANLINE_TIME_COUNT 16
507
508#define T30_DATA_FORMAT_SFF 0
509#define T30_DATA_FORMAT_ASCII 1
510#define T30_DATA_FORMAT_NATIVE 2
511#define T30_DATA_FORMAT_COUNT 3
512
513
514#define T30_OPERATING_MODE_STANDARD 0
515#define T30_OPERATING_MODE_CLASS2 1
516#define T30_OPERATING_MODE_CLASS1 2
517#define T30_OPERATING_MODE_CAPI 3
518#define T30_OPERATING_MODE_CAPI_NEG 4
519#define T30_OPERATING_MODE_COUNT 5
520
521/* EDATA transmit messages */
522#define EDATA_T30_DIS 0x01
523#define EDATA_T30_FTT 0x02
524#define EDATA_T30_MCF 0x03
525#define EDATA_T30_PARAMETERS 0x04
526
527/* EDATA receive messages */
528#define EDATA_T30_DCS 0x81
529#define EDATA_T30_TRAIN_OK 0x82
530#define EDATA_T30_EOP 0x83
531#define EDATA_T30_MPS 0x84
532#define EDATA_T30_EOM 0x85
533#define EDATA_T30_DTC 0x86
534#define EDATA_T30_PAGE_END 0x87 /* Indicates end of page data. Reserved, but not implemented ! */
535#define EDATA_T30_EOP_CAPI 0x88
536
537
538#define T30_SUCCESS 0
539#define T30_ERR_NO_DIS_RECEIVED 1
540#define T30_ERR_TIMEOUT_NO_RESPONSE 2
541#define T30_ERR_RETRY_NO_RESPONSE 3
542#define T30_ERR_TOO_MANY_REPEATS 4
543#define T30_ERR_UNEXPECTED_MESSAGE 5
544#define T30_ERR_UNEXPECTED_DCN 6
545#define T30_ERR_DTC_UNSUPPORTED 7
546#define T30_ERR_ALL_RATES_FAILED 8
547#define T30_ERR_TOO_MANY_TRAINS 9
548#define T30_ERR_RECEIVE_CORRUPTED 10
549#define T30_ERR_UNEXPECTED_DISC 11
550#define T30_ERR_APPLICATION_DISC 12
551#define T30_ERR_INCOMPATIBLE_DIS 13
552#define T30_ERR_INCOMPATIBLE_DCS 14
553#define T30_ERR_TIMEOUT_NO_COMMAND 15
554#define T30_ERR_RETRY_NO_COMMAND 16
555#define T30_ERR_TIMEOUT_COMMAND_TOO_LONG 17
556#define T30_ERR_TIMEOUT_RESPONSE_TOO_LONG 18
557#define T30_ERR_NOT_IDENTIFIED 19
558#define T30_ERR_SUPERVISORY_TIMEOUT 20
559#define T30_ERR_TOO_LONG_SCAN_LINE 21
560/* #define T30_ERR_RETRY_NO_PAGE_AFTER_MPS 22 */
561#define T30_ERR_RETRY_NO_PAGE_RECEIVED 23
562#define T30_ERR_RETRY_NO_DCS_AFTER_FTT 24
563#define T30_ERR_RETRY_NO_DCS_AFTER_EOM 25
564#define T30_ERR_RETRY_NO_DCS_AFTER_MPS 26
565#define T30_ERR_RETRY_NO_DCN_AFTER_MCF 27
566#define T30_ERR_RETRY_NO_DCN_AFTER_RTN 28
567#define T30_ERR_RETRY_NO_CFR 29
568#define T30_ERR_RETRY_NO_MCF_AFTER_EOP 30
569#define T30_ERR_RETRY_NO_MCF_AFTER_EOM 31
570#define T30_ERR_RETRY_NO_MCF_AFTER_MPS 32
571#define T30_ERR_SUB_SEP_UNSUPPORTED 33
572#define T30_ERR_PWD_UNSUPPORTED 34
573#define T30_ERR_SUB_SEP_PWD_UNSUPPORTED 35
574#define T30_ERR_INVALID_COMMAND_FRAME 36
575#define T30_ERR_UNSUPPORTED_PAGE_CODING 37
576#define T30_ERR_INVALID_PAGE_CODING 38
577#define T30_ERR_INCOMPATIBLE_PAGE_CONFIG 39
578#define T30_ERR_TIMEOUT_FROM_APPLICATION 40
579#define T30_ERR_V34FAX_NO_REACTION_ON_MARK 41
580#define T30_ERR_V34FAX_TRAINING_TIMEOUT 42
581#define T30_ERR_V34FAX_UNEXPECTED_V21 43
582#define T30_ERR_V34FAX_PRIMARY_CTS_ON 44
583#define T30_ERR_V34FAX_TURNAROUND_POLLING 45
584#define T30_ERR_V34FAX_V8_INCOMPATIBILITY 46
585
586
587#define T30_CONTROL_BIT_DISABLE_FINE 0x0001
588#define T30_CONTROL_BIT_ENABLE_ECM 0x0002
589#define T30_CONTROL_BIT_ECM_64_BYTES 0x0004
590#define T30_CONTROL_BIT_ENABLE_2D_CODING 0x0008
591#define T30_CONTROL_BIT_ENABLE_T6_CODING 0x0010
592#define T30_CONTROL_BIT_ENABLE_UNCOMPR 0x0020
593#define T30_CONTROL_BIT_ACCEPT_POLLING 0x0040
594#define T30_CONTROL_BIT_REQUEST_POLLING 0x0080
595#define T30_CONTROL_BIT_MORE_DOCUMENTS 0x0100
596#define T30_CONTROL_BIT_ACCEPT_SUBADDRESS 0x0200
597#define T30_CONTROL_BIT_ACCEPT_SEL_POLLING 0x0400
598#define T30_CONTROL_BIT_ACCEPT_PASSWORD 0x0800
599#define T30_CONTROL_BIT_ENABLE_V34FAX 0x1000
600#define T30_CONTROL_BIT_EARLY_CONNECT 0x2000
601
602#define T30_CONTROL_BIT_ALL_FEATURES (T30_CONTROL_BIT_ENABLE_ECM | T30_CONTROL_BIT_ENABLE_2D_CODING | T30_CONTROL_BIT_ENABLE_T6_CODING | T30_CONTROL_BIT_ENABLE_UNCOMPR | T30_CONTROL_BIT_ENABLE_V34FAX)
603
604#define T30_FEATURE_BIT_FINE 0x0001
605#define T30_FEATURE_BIT_ECM 0x0002
606#define T30_FEATURE_BIT_ECM_64_BYTES 0x0004
607#define T30_FEATURE_BIT_2D_CODING 0x0008
608#define T30_FEATURE_BIT_T6_CODING 0x0010
609#define T30_FEATURE_BIT_UNCOMPR_ENABLED 0x0020
610#define T30_FEATURE_BIT_POLLING 0x0040
611#define T30_FEATURE_BIT_MORE_DOCUMENTS 0x0100
612#define T30_FEATURE_BIT_V34FAX 0x1000
613
614
615#define T30_NSF_CONTROL_BIT_ENABLE_NSF 0x0001
616#define T30_NSF_CONTROL_BIT_RAW_INFO 0x0002
617#define T30_NSF_CONTROL_BIT_NEGOTIATE_IND 0x0004
618#define T30_NSF_CONTROL_BIT_NEGOTIATE_RESP 0x0008
619
620#define T30_NSF_ELEMENT_NSF_FIF 0x00
621#define T30_NSF_ELEMENT_NSC_FIF 0x01
622#define T30_NSF_ELEMENT_NSS_FIF 0x02
623#define T30_NSF_ELEMENT_COMPANY_NAME 0x03
624
625
626/*------------------------------------------------------------------*/
627/* Analog modem definitions */
628/*------------------------------------------------------------------*/
629
630typedef struct async_s ASYNC_FORMAT;
631struct async_s {
632 unsigned pe:1;
633 unsigned parity:2;
634 unsigned spare:2;
635 unsigned stp:1;
636 unsigned ch_len:2; /* 3th octett in CAI */
637};
638
639
640/*------------------------------------------------------------------*/
641/* PLCI/NCCI states */
642/*------------------------------------------------------------------*/
643
644#define IDLE 0
645#define OUTG_CON_PENDING 1
646#define INC_CON_PENDING 2
647#define INC_CON_ALERT 3
648#define INC_CON_ACCEPT 4
649#define INC_ACT_PENDING 5
650#define LISTENING 6
651#define CONNECTED 7
652#define OUTG_DIS_PENDING 8
653#define INC_DIS_PENDING 9
654#define LOCAL_CONNECT 10
655#define INC_RES_PENDING 11
656#define OUTG_RES_PENDING 12
657#define SUSPENDING 13
658#define ADVANCED_VOICE_SIG 14
659#define ADVANCED_VOICE_NOSIG 15
660#define RESUMING 16
661#define INC_CON_CONNECTED_ALERT 17
662#define OUTG_REJ_PENDING 18
663
664
665/*------------------------------------------------------------------*/
666/* auxiliary states for supplementary services */
667/*------------------------------------------------------------------*/
668
669#define IDLE 0
670#define HOLD_REQUEST 1
671#define HOLD_INDICATE 2
672#define CALL_HELD 3
673#define RETRIEVE_REQUEST 4
674#define RETRIEVE_INDICATION 5
675
676/*------------------------------------------------------------------*/
677/* Capi IE + Msg types */
678/*------------------------------------------------------------------*/
679#define ESC_CAUSE 0x800 | CAU /* Escape cause element */
680#define ESC_MSGTYPE 0x800 | MSGTYPEIE /* Escape message type */
681#define ESC_CHI 0x800 | CHI /* Escape channel id */
682#define ESC_LAW 0x800 | BC /* Escape law info */
683#define ESC_CR 0x800 | CRIE /* Escape CallReference */
684#define ESC_PROFILE 0x800 | PROFILEIE /* Escape profile */
685#define ESC_SSEXT 0x800 | SSEXTIE /* Escape Supplem. Serv.*/
686#define ESC_VSWITCH 0x800 | VSWITCHIE /* Escape VSwitch */
687#define CST 0x14 /* Call State i.e. */
688#define PI 0x1E /* Progress Indicator */
689#define NI 0x27 /* Notification Ind */
690#define CONN_NR 0x4C /* Connected Number */
691#define CONG_RNR 0xBF /* Congestion RNR */
692#define CONG_RR 0xB0 /* Congestion RR */
693#define RESERVED 0xFF /* Res. for future use */
694#define ON_BOARD_CODEC 0x02 /* external controller */
695#define HANDSET 0x04 /* Codec+Handset(Pro11) */
696#define HOOK_SUPPORT 0x01 /* activate Hook signal */
697#define SCR 0x7a /* unscreened number */
698
699#define HOOK_OFF_REQ 0x9001 /* internal conn req */
700#define HOOK_ON_REQ 0x9002 /* internal disc req */
701#define SUSPEND_REQ 0x9003 /* internal susp req */
702#define RESUME_REQ 0x9004 /* internal resume req */
703#define USELAW_REQ 0x9005 /* internal law req */
704#define LISTEN_SIG_ASSIGN_PEND 0x9006
705#define PERM_LIST_REQ 0x900a /* permanent conn DCE */
706#define C_HOLD_REQ 0x9011
707#define C_RETRIEVE_REQ 0x9012
708#define C_NCR_FAC_REQ 0x9013
709#define PERM_COD_ASSIGN 0x9014
710#define PERM_COD_CALL 0x9015
711#define PERM_COD_HOOK 0x9016
712#define PERM_COD_CONN_PEND 0x9017 /* wait for connect_con */
713#define PTY_REQ_PEND 0x9018
714#define CD_REQ_PEND 0x9019
715#define CF_START_PEND 0x901a
716#define CF_STOP_PEND 0x901b
717#define ECT_REQ_PEND 0x901c
718#define GETSERV_REQ_PEND 0x901d
719#define BLOCK_PLCI 0x901e
720#define INTERR_NUMBERS_REQ_PEND 0x901f
721#define INTERR_DIVERSION_REQ_PEND 0x9020
722#define MWI_ACTIVATE_REQ_PEND 0x9021
723#define MWI_DEACTIVATE_REQ_PEND 0x9022
724#define SSEXT_REQ_COMMAND 0x9023
725#define SSEXT_NC_REQ_COMMAND 0x9024
726#define START_L1_SIG_ASSIGN_PEND 0x9025
727#define REM_L1_SIG_ASSIGN_PEND 0x9026
728#define CONF_BEGIN_REQ_PEND 0x9027
729#define CONF_ADD_REQ_PEND 0x9028
730#define CONF_SPLIT_REQ_PEND 0x9029
731#define CONF_DROP_REQ_PEND 0x902a
732#define CONF_ISOLATE_REQ_PEND 0x902b
733#define CONF_REATTACH_REQ_PEND 0x902c
734#define VSWITCH_REQ_PEND 0x902d
735#define GET_MWI_STATE 0x902e
736#define CCBS_REQUEST_REQ_PEND 0x902f
737#define CCBS_DEACTIVATE_REQ_PEND 0x9030
738#define CCBS_INTERROGATE_REQ_PEND 0x9031
739
740#define NO_INTERNAL_COMMAND 0
741#define DTMF_COMMAND_1 1
742#define DTMF_COMMAND_2 2
743#define DTMF_COMMAND_3 3
744#define MIXER_COMMAND_1 4
745#define MIXER_COMMAND_2 5
746#define MIXER_COMMAND_3 6
747#define ADV_VOICE_COMMAND_CONNECT_1 7
748#define ADV_VOICE_COMMAND_CONNECT_2 8
749#define ADV_VOICE_COMMAND_CONNECT_3 9
750#define ADV_VOICE_COMMAND_DISCONNECT_1 10
751#define ADV_VOICE_COMMAND_DISCONNECT_2 11
752#define ADV_VOICE_COMMAND_DISCONNECT_3 12
753#define ADJUST_B_RESTORE_1 13
754#define ADJUST_B_RESTORE_2 14
755#define RESET_B3_COMMAND_1 15
756#define SELECT_B_COMMAND_1 16
757#define FAX_CONNECT_INFO_COMMAND_1 17
758#define FAX_CONNECT_INFO_COMMAND_2 18
759#define FAX_ADJUST_B23_COMMAND_1 19
760#define FAX_ADJUST_B23_COMMAND_2 20
761#define EC_COMMAND_1 21
762#define EC_COMMAND_2 22
763#define EC_COMMAND_3 23
764#define RTP_CONNECT_B3_REQ_COMMAND_1 24
765#define RTP_CONNECT_B3_REQ_COMMAND_2 25
766#define RTP_CONNECT_B3_REQ_COMMAND_3 26
767#define RTP_CONNECT_B3_RES_COMMAND_1 27
768#define RTP_CONNECT_B3_RES_COMMAND_2 28
769#define RTP_CONNECT_B3_RES_COMMAND_3 29
770#define HOLD_SAVE_COMMAND_1 30
771#define RETRIEVE_RESTORE_COMMAND_1 31
772#define FAX_DISCONNECT_COMMAND_1 32
773#define FAX_DISCONNECT_COMMAND_2 33
774#define FAX_DISCONNECT_COMMAND_3 34
775#define FAX_EDATA_ACK_COMMAND_1 35
776#define FAX_EDATA_ACK_COMMAND_2 36
777#define FAX_CONNECT_ACK_COMMAND_1 37
778#define FAX_CONNECT_ACK_COMMAND_2 38
779#define STD_INTERNAL_COMMAND_COUNT 39
780
781#define UID 0x2d /* User Id for Mgmt */
782
783#define CALL_DIR_OUT 0x01 /* call direction of initial call */
784#define CALL_DIR_IN 0x02
785#define CALL_DIR_ORIGINATE 0x04 /* DTE/DCE direction according to */
786#define CALL_DIR_ANSWER 0x08 /* state of B-Channel Operation */
787#define CALL_DIR_FORCE_OUTG_NL 0x10 /* for RESET_B3 reconnect, after DISC_B3... */
788
789#define AWAITING_MANUF_CON 0x80 /* command spoofing flags */
790#define SPOOFING_REQUIRED 0xff
791#define AWAITING_SELECT_B 0xef
792
793/*------------------------------------------------------------------*/
794/* B_CTRL / DSP_CTRL */
795/*------------------------------------------------------------------*/
796
797#define DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS 0x01
798#define DSP_CTRL_SET_BCHANNEL_PASSIVATION_BRI 0x02
799#define DSP_CTRL_SET_DTMF_PARAMETERS 0x03
800
801#define MANUFACTURER_FEATURE_SLAVE_CODEC 0x00000001L
802#define MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS 0x00000002L
803#define MANUFACTURER_FEATURE_HARDDTMF 0x00000004L
804#define MANUFACTURER_FEATURE_SOFTDTMF_SEND 0x00000008L
805#define MANUFACTURER_FEATURE_DTMF_PARAMETERS 0x00000010L
806#define MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE 0x00000020L
807#define MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD 0x00000040L
808#define MANUFACTURER_FEATURE_V18 0x00000080L
809#define MANUFACTURER_FEATURE_MIXER_CH_CH 0x00000100L
810#define MANUFACTURER_FEATURE_MIXER_CH_PC 0x00000200L
811#define MANUFACTURER_FEATURE_MIXER_PC_CH 0x00000400L
812#define MANUFACTURER_FEATURE_MIXER_PC_PC 0x00000800L
813#define MANUFACTURER_FEATURE_ECHO_CANCELLER 0x00001000L
814#define MANUFACTURER_FEATURE_RTP 0x00002000L
815#define MANUFACTURER_FEATURE_T38 0x00004000L
816#define MANUFACTURER_FEATURE_TRANSP_DELIVERY_CONF 0x00008000L
817#define MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL 0x00010000L
818#define MANUFACTURER_FEATURE_OOB_CHANNEL 0x00020000L
819#define MANUFACTURER_FEATURE_IN_BAND_CHANNEL 0x00040000L
820#define MANUFACTURER_FEATURE_IN_BAND_FEATURE 0x00080000L
821#define MANUFACTURER_FEATURE_PIAFS 0x00100000L
822#define MANUFACTURER_FEATURE_DTMF_TONE 0x00200000L
823#define MANUFACTURER_FEATURE_FAX_PAPER_FORMATS 0x00400000L
824#define MANUFACTURER_FEATURE_OK_FC_LABEL 0x00800000L
825#define MANUFACTURER_FEATURE_VOWN 0x01000000L
826#define MANUFACTURER_FEATURE_XCONNECT 0x02000000L
827#define MANUFACTURER_FEATURE_DMACONNECT 0x04000000L
828#define MANUFACTURER_FEATURE_AUDIO_TAP 0x08000000L
829#define MANUFACTURER_FEATURE_FAX_NONSTANDARD 0x10000000L
830
831/*------------------------------------------------------------------*/
832/* DTMF interface to IDI */
833/*------------------------------------------------------------------*/
834
835
836#define DTMF_DIGIT_TONE_LOW_GROUP_697_HZ 0x00
837#define DTMF_DIGIT_TONE_LOW_GROUP_770_HZ 0x01
838#define DTMF_DIGIT_TONE_LOW_GROUP_852_HZ 0x02
839#define DTMF_DIGIT_TONE_LOW_GROUP_941_HZ 0x03
840#define DTMF_DIGIT_TONE_LOW_GROUP_MASK 0x03
841#define DTMF_DIGIT_TONE_HIGH_GROUP_1209_HZ 0x00
842#define DTMF_DIGIT_TONE_HIGH_GROUP_1336_HZ 0x04
843#define DTMF_DIGIT_TONE_HIGH_GROUP_1477_HZ 0x08
844#define DTMF_DIGIT_TONE_HIGH_GROUP_1633_HZ 0x0c
845#define DTMF_DIGIT_TONE_HIGH_GROUP_MASK 0x0c
846#define DTMF_DIGIT_TONE_CODE_0 0x07
847#define DTMF_DIGIT_TONE_CODE_1 0x00
848#define DTMF_DIGIT_TONE_CODE_2 0x04
849#define DTMF_DIGIT_TONE_CODE_3 0x08
850#define DTMF_DIGIT_TONE_CODE_4 0x01
851#define DTMF_DIGIT_TONE_CODE_5 0x05
852#define DTMF_DIGIT_TONE_CODE_6 0x09
853#define DTMF_DIGIT_TONE_CODE_7 0x02
854#define DTMF_DIGIT_TONE_CODE_8 0x06
855#define DTMF_DIGIT_TONE_CODE_9 0x0a
856#define DTMF_DIGIT_TONE_CODE_STAR 0x03
857#define DTMF_DIGIT_TONE_CODE_HASHMARK 0x0b
858#define DTMF_DIGIT_TONE_CODE_A 0x0c
859#define DTMF_DIGIT_TONE_CODE_B 0x0d
860#define DTMF_DIGIT_TONE_CODE_C 0x0e
861#define DTMF_DIGIT_TONE_CODE_D 0x0f
862
863#define DTMF_UDATA_REQUEST_SEND_DIGITS 16
864#define DTMF_UDATA_REQUEST_ENABLE_RECEIVER 17
865#define DTMF_UDATA_REQUEST_DISABLE_RECEIVER 18
866#define DTMF_UDATA_INDICATION_DIGITS_SENT 16
867#define DTMF_UDATA_INDICATION_DIGITS_RECEIVED 17
868#define DTMF_UDATA_INDICATION_MODEM_CALLING_TONE 18
869#define DTMF_UDATA_INDICATION_FAX_CALLING_TONE 19
870#define DTMF_UDATA_INDICATION_ANSWER_TONE 20
871
872#define UDATA_REQUEST_MIXER_TAP_DATA 27
873#define UDATA_INDICATION_MIXER_TAP_DATA 27
874
875#define DTMF_LISTEN_ACTIVE_FLAG 0x01
876#define DTMF_SEND_DIGIT_FLAG 0x01
877
878
879/*------------------------------------------------------------------*/
880/* Mixer interface to IDI */
881/*------------------------------------------------------------------*/
882
883
884#define LI2_FLAG_PCCONNECT_A_B 0x40000000
885#define LI2_FLAG_PCCONNECT_B_A 0x80000000
886
887#define MIXER_BCHANNELS_BRI 2
888#define MIXER_IC_CHANNELS_BRI MIXER_BCHANNELS_BRI
889#define MIXER_IC_CHANNEL_BASE MIXER_BCHANNELS_BRI
890#define MIXER_CHANNELS_BRI (MIXER_BCHANNELS_BRI + MIXER_IC_CHANNELS_BRI)
891#define MIXER_CHANNELS_PRI 32
892
893typedef struct li_config_s LI_CONFIG;
894
895struct xconnect_card_address_s {
896 dword low;
897 dword high;
898};
899
900struct xconnect_transfer_address_s {
901 struct xconnect_card_address_s card_address;
902 dword offset;
903};
904
905struct li_config_s {
906 DIVA_CAPI_ADAPTER *adapter;
907 PLCI *plci;
908 struct xconnect_transfer_address_s send_b;
909 struct xconnect_transfer_address_s send_pc;
910 byte *flag_table; /* dword aligned and sized */
911 byte *coef_table; /* dword aligned and sized */
912 byte channel;
913 byte curchnl;
914 byte chflags;
915};
916
917extern LI_CONFIG *li_config_table;
918extern word li_total_channels;
919
920#define LI_CHANNEL_INVOLVED 0x01
921#define LI_CHANNEL_ACTIVE 0x02
922#define LI_CHANNEL_TX_DATA 0x04
923#define LI_CHANNEL_RX_DATA 0x08
924#define LI_CHANNEL_CONFERENCE 0x10
925#define LI_CHANNEL_ADDRESSES_SET 0x80
926
927#define LI_CHFLAG_MONITOR 0x01
928#define LI_CHFLAG_MIX 0x02
929#define LI_CHFLAG_LOOP 0x04
930
931#define LI_FLAG_INTERCONNECT 0x01
932#define LI_FLAG_MONITOR 0x02
933#define LI_FLAG_MIX 0x04
934#define LI_FLAG_PCCONNECT 0x08
935#define LI_FLAG_CONFERENCE 0x10
936#define LI_FLAG_ANNOUNCEMENT 0x20
937
938#define LI_COEF_CH_CH 0x01
939#define LI_COEF_CH_PC 0x02
940#define LI_COEF_PC_CH 0x04
941#define LI_COEF_PC_PC 0x08
942#define LI_COEF_CH_CH_SET 0x10
943#define LI_COEF_CH_PC_SET 0x20
944#define LI_COEF_PC_CH_SET 0x40
945#define LI_COEF_PC_PC_SET 0x80
946
947#define LI_REQ_SILENT_UPDATE 0xffff
948
949#define LI_PLCI_B_LAST_FLAG ((dword) 0x80000000L)
950#define LI_PLCI_B_DISC_FLAG ((dword) 0x40000000L)
951#define LI_PLCI_B_SKIP_FLAG ((dword) 0x20000000L)
952#define LI_PLCI_B_FLAG_MASK ((dword) 0xe0000000L)
953
954#define UDATA_REQUEST_SET_MIXER_COEFS_BRI 24
955#define UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC 25
956#define UDATA_REQUEST_SET_MIXER_COEFS_PRI_ASYN 26
957#define UDATA_INDICATION_MIXER_COEFS_SET 24
958
959#define MIXER_FEATURE_ENABLE_TX_DATA 0x0001
960#define MIXER_FEATURE_ENABLE_RX_DATA 0x0002
961
962#define MIXER_COEF_LINE_CHANNEL_MASK 0x1f
963#define MIXER_COEF_LINE_FROM_PC_FLAG 0x20
964#define MIXER_COEF_LINE_TO_PC_FLAG 0x40
965#define MIXER_COEF_LINE_ROW_FLAG 0x80
966
967#define UDATA_REQUEST_XCONNECT_FROM 28
968#define UDATA_INDICATION_XCONNECT_FROM 28
969#define UDATA_REQUEST_XCONNECT_TO 29
970#define UDATA_INDICATION_XCONNECT_TO 29
971
972#define XCONNECT_CHANNEL_PORT_B 0x0000
973#define XCONNECT_CHANNEL_PORT_PC 0x8000
974#define XCONNECT_CHANNEL_PORT_MASK 0x8000
975#define XCONNECT_CHANNEL_NUMBER_MASK 0x7fff
976#define XCONNECT_CHANNEL_PORT_COUNT 2
977
978#define XCONNECT_SUCCESS 0x0000
979#define XCONNECT_ERROR 0x0001
980
981
982/*------------------------------------------------------------------*/
983/* Echo canceller interface to IDI */
984/*------------------------------------------------------------------*/
985
986
987#define PRIVATE_ECHO_CANCELLER 0
988
989#define PRIV_SELECTOR_ECHO_CANCELLER 255
990
991#define EC_ENABLE_OPERATION 1
992#define EC_DISABLE_OPERATION 2
993#define EC_FREEZE_COEFFICIENTS 3
994#define EC_RESUME_COEFFICIENT_UPDATE 4
995#define EC_RESET_COEFFICIENTS 5
996
997#define EC_DISABLE_NON_LINEAR_PROCESSING 0x0001
998#define EC_DO_NOT_REQUIRE_REVERSALS 0x0002
999#define EC_DETECT_DISABLE_TONE 0x0004
1000
1001#define EC_SUCCESS 0
1002#define EC_UNSUPPORTED_OPERATION 1
1003
1004#define EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ 1
1005#define EC_BYPASS_DUE_TO_REVERSED_2100HZ 2
1006#define EC_BYPASS_RELEASED 3
1007
1008#define DSP_CTRL_SET_LEC_PARAMETERS 0x05
1009
1010#define LEC_ENABLE_ECHO_CANCELLER 0x0001
1011#define LEC_ENABLE_2100HZ_DETECTOR 0x0002
1012#define LEC_REQUIRE_2100HZ_REVERSALS 0x0004
1013#define LEC_MANUAL_DISABLE 0x0008
1014#define LEC_ENABLE_NONLINEAR_PROCESSING 0x0010
1015#define LEC_FREEZE_COEFFICIENTS 0x0020
1016#define LEC_RESET_COEFFICIENTS 0x8000
1017
1018#define LEC_MAX_SUPPORTED_TAIL_LENGTH 32
1019
1020#define LEC_UDATA_INDICATION_DISABLE_DETECT 9
1021
1022#define LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ 0x00
1023#define LEC_DISABLE_TYPE_REVERSED_2100HZ 0x01
1024#define LEC_DISABLE_RELEASED 0x02
1025
1026
1027/*------------------------------------------------------------------*/
1028/* RTP interface to IDI */
1029/*------------------------------------------------------------------*/
1030
1031
1032#define B1_RTP 31
1033#define B2_RTP 31
1034#define B3_RTP 31
1035
1036#define PRIVATE_RTP 1
1037
1038#define RTP_PRIM_PAYLOAD_PCMU_8000 0
1039#define RTP_PRIM_PAYLOAD_1016_8000 1
1040#define RTP_PRIM_PAYLOAD_G726_32_8000 2
1041#define RTP_PRIM_PAYLOAD_GSM_8000 3
1042#define RTP_PRIM_PAYLOAD_G723_8000 4
1043#define RTP_PRIM_PAYLOAD_DVI4_8000 5
1044#define RTP_PRIM_PAYLOAD_DVI4_16000 6
1045#define RTP_PRIM_PAYLOAD_LPC_8000 7
1046#define RTP_PRIM_PAYLOAD_PCMA_8000 8
1047#define RTP_PRIM_PAYLOAD_G722_16000 9
1048#define RTP_PRIM_PAYLOAD_QCELP_8000 12
1049#define RTP_PRIM_PAYLOAD_G728_8000 14
1050#define RTP_PRIM_PAYLOAD_G729_8000 18
1051#define RTP_PRIM_PAYLOAD_GSM_HR_8000 30
1052#define RTP_PRIM_PAYLOAD_GSM_EFR_8000 31
1053
1054#define RTP_ADD_PAYLOAD_BASE 32
1055#define RTP_ADD_PAYLOAD_RED 32
1056#define RTP_ADD_PAYLOAD_CN_8000 33
1057#define RTP_ADD_PAYLOAD_DTMF 34
1058
1059#define RTP_SUCCESS 0
1060#define RTP_ERR_SSRC_OR_PAYLOAD_CHANGE 1
1061
1062#define UDATA_REQUEST_RTP_RECONFIGURE 64
1063#define UDATA_INDICATION_RTP_CHANGE 65
1064#define BUDATA_REQUEST_QUERY_RTCP_REPORT 1
1065#define BUDATA_INDICATION_RTCP_REPORT 1
1066
1067#define RTP_CONNECT_OPTION_DISC_ON_SSRC_CHANGE 0x00000001L
1068#define RTP_CONNECT_OPTION_DISC_ON_PT_CHANGE 0x00000002L
1069#define RTP_CONNECT_OPTION_DISC_ON_UNKNOWN_PT 0x00000004L
1070#define RTP_CONNECT_OPTION_NO_SILENCE_TRANSMIT 0x00010000L
1071
1072#define RTP_PAYLOAD_OPTION_VOICE_ACTIVITY_DETECT 0x0001
1073#define RTP_PAYLOAD_OPTION_DISABLE_POST_FILTER 0x0002
1074#define RTP_PAYLOAD_OPTION_G723_LOW_CODING_RATE 0x0100
1075
1076#define RTP_PACKET_FILTER_IGNORE_UNKNOWN_SSRC 0x00000001L
1077
1078#define RTP_CHANGE_FLAG_SSRC_CHANGE 0x00000001L
1079#define RTP_CHANGE_FLAG_PAYLOAD_TYPE_CHANGE 0x00000002L
1080#define RTP_CHANGE_FLAG_UNKNOWN_PAYLOAD_TYPE 0x00000004L
1081
1082
1083/*------------------------------------------------------------------*/
1084/* T.38 interface to IDI */
1085/*------------------------------------------------------------------*/
1086
1087
1088#define B1_T38 30
1089#define B2_T38 30
1090#define B3_T38 30
1091
1092#define PRIVATE_T38 2
1093
1094
1095/*------------------------------------------------------------------*/
1096/* PIAFS interface to IDI */
1097/*------------------------------------------------------------------*/
1098
1099
1100#define B1_PIAFS 29
1101#define B2_PIAFS 29
1102
1103#define PRIVATE_PIAFS 29
1104
1105/*
1106 B2 configuration for PIAFS:
1107 +---------------------+------+-----------------------------------------+
1108 | PIAFS Protocol | byte | Bit 1 - Protocol Speed |
1109 | Speed configuration | | 0 - 32K |
1110 | | | 1 - 64K (default) |
1111 | | | Bit 2 - Variable Protocol Speed |
1112 | | | 0 - Speed is fix |
1113 | | | 1 - Speed is variable (default) |
1114 +---------------------+------+-----------------------------------------+
1115 | Direction | word | Enable compression/decompression for |
1116 | | | 0: All direction |
1117 | | | 1: disable outgoing data |
1118 | | | 2: disable incoming data |
1119 | | | 3: disable both direction (default) |
1120 +---------------------+------+-----------------------------------------+
1121 | Number of code | word | Parameter P1 of V.42bis in accordance |
1122 | words | | with V.42bis |
1123 +---------------------+------+-----------------------------------------+
1124 | Maximum String | word | Parameter P2 of V.42bis in accordance |
1125 | Length | | with V.42bis |
1126 +---------------------+------+-----------------------------------------+
1127 | control (UDATA) | byte | enable PIAFS control communication |
1128 | abilities | | |
1129 +---------------------+------+-----------------------------------------+
1130*/
1131#define PIAFS_UDATA_ABILITIES 0x80
1132
1133/*------------------------------------------------------------------*/
1134/* FAX SUB/SEP/PWD extension */
1135/*------------------------------------------------------------------*/
1136
1137
1138#define PRIVATE_FAX_SUB_SEP_PWD 3
1139
1140
1141
1142/*------------------------------------------------------------------*/
1143/* V.18 extension */
1144/*------------------------------------------------------------------*/
1145
1146
1147#define PRIVATE_V18 4
1148
1149
1150
1151/*------------------------------------------------------------------*/
1152/* DTMF TONE extension */
1153/*------------------------------------------------------------------*/
1154
1155
1156#define DTMF_GET_SUPPORTED_DETECT_CODES 0xf8
1157#define DTMF_GET_SUPPORTED_SEND_CODES 0xf9
1158#define DTMF_LISTEN_TONE_START 0xfa
1159#define DTMF_LISTEN_TONE_STOP 0xfb
1160#define DTMF_SEND_TONE 0xfc
1161#define DTMF_LISTEN_MF_START 0xfd
1162#define DTMF_LISTEN_MF_STOP 0xfe
1163#define DTMF_SEND_MF 0xff
1164
1165#define DTMF_MF_DIGIT_TONE_CODE_1 0x10
1166#define DTMF_MF_DIGIT_TONE_CODE_2 0x11
1167#define DTMF_MF_DIGIT_TONE_CODE_3 0x12
1168#define DTMF_MF_DIGIT_TONE_CODE_4 0x13
1169#define DTMF_MF_DIGIT_TONE_CODE_5 0x14
1170#define DTMF_MF_DIGIT_TONE_CODE_6 0x15
1171#define DTMF_MF_DIGIT_TONE_CODE_7 0x16
1172#define DTMF_MF_DIGIT_TONE_CODE_8 0x17
1173#define DTMF_MF_DIGIT_TONE_CODE_9 0x18
1174#define DTMF_MF_DIGIT_TONE_CODE_0 0x19
1175#define DTMF_MF_DIGIT_TONE_CODE_K1 0x1a
1176#define DTMF_MF_DIGIT_TONE_CODE_K2 0x1b
1177#define DTMF_MF_DIGIT_TONE_CODE_KP 0x1c
1178#define DTMF_MF_DIGIT_TONE_CODE_S1 0x1d
1179#define DTMF_MF_DIGIT_TONE_CODE_ST 0x1e
1180
1181#define DTMF_DIGIT_CODE_COUNT 16
1182#define DTMF_MF_DIGIT_CODE_BASE DSP_DTMF_DIGIT_CODE_COUNT
1183#define DTMF_MF_DIGIT_CODE_COUNT 15
1184#define DTMF_TOTAL_DIGIT_CODE_COUNT (DSP_MF_DIGIT_CODE_BASE + DSP_MF_DIGIT_CODE_COUNT)
1185
1186#define DTMF_TONE_DIGIT_BASE 0x80
1187
1188#define DTMF_SIGNAL_NO_TONE (DTMF_TONE_DIGIT_BASE + 0)
1189#define DTMF_SIGNAL_UNIDENTIFIED_TONE (DTMF_TONE_DIGIT_BASE + 1)
1190
1191#define DTMF_SIGNAL_DIAL_TONE (DTMF_TONE_DIGIT_BASE + 2)
1192#define DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE (DTMF_TONE_DIGIT_BASE + 3)
1193#define DTMF_SIGNAL_SPECIAL_DIAL_TONE (DTMF_TONE_DIGIT_BASE + 4) /* stutter dial tone */
1194#define DTMF_SIGNAL_SECOND_DIAL_TONE (DTMF_TONE_DIGIT_BASE + 5)
1195#define DTMF_SIGNAL_RINGING_TONE (DTMF_TONE_DIGIT_BASE + 6)
1196#define DTMF_SIGNAL_SPECIAL_RINGING_TONE (DTMF_TONE_DIGIT_BASE + 7)
1197#define DTMF_SIGNAL_BUSY_TONE (DTMF_TONE_DIGIT_BASE + 8)
1198#define DTMF_SIGNAL_CONGESTION_TONE (DTMF_TONE_DIGIT_BASE + 9) /* reorder tone */
1199#define DTMF_SIGNAL_SPECIAL_INFORMATION_TONE (DTMF_TONE_DIGIT_BASE + 10)
1200#define DTMF_SIGNAL_COMFORT_TONE (DTMF_TONE_DIGIT_BASE + 11)
1201#define DTMF_SIGNAL_HOLD_TONE (DTMF_TONE_DIGIT_BASE + 12)
1202#define DTMF_SIGNAL_RECORD_TONE (DTMF_TONE_DIGIT_BASE + 13)
1203#define DTMF_SIGNAL_CALLER_WAITING_TONE (DTMF_TONE_DIGIT_BASE + 14)
1204#define DTMF_SIGNAL_CALL_WAITING_TONE (DTMF_TONE_DIGIT_BASE + 15)
1205#define DTMF_SIGNAL_PAY_TONE (DTMF_TONE_DIGIT_BASE + 16)
1206#define DTMF_SIGNAL_POSITIVE_INDICATION_TONE (DTMF_TONE_DIGIT_BASE + 17)
1207#define DTMF_SIGNAL_NEGATIVE_INDICATION_TONE (DTMF_TONE_DIGIT_BASE + 18)
1208#define DTMF_SIGNAL_WARNING_TONE (DTMF_TONE_DIGIT_BASE + 19)
1209#define DTMF_SIGNAL_INTRUSION_TONE (DTMF_TONE_DIGIT_BASE + 20)
1210#define DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE (DTMF_TONE_DIGIT_BASE + 21)
1211#define DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE (DTMF_TONE_DIGIT_BASE + 22)
1212#define DTMF_SIGNAL_CPE_ALERTING_SIGNAL (DTMF_TONE_DIGIT_BASE + 23)
1213#define DTMF_SIGNAL_OFF_HOOK_WARNING_TONE (DTMF_TONE_DIGIT_BASE + 24)
1214
1215#define DTMF_SIGNAL_INTERCEPT_TONE (DTMF_TONE_DIGIT_BASE + 63)
1216
1217#define DTMF_SIGNAL_MODEM_CALLING_TONE (DTMF_TONE_DIGIT_BASE + 64)
1218#define DTMF_SIGNAL_FAX_CALLING_TONE (DTMF_TONE_DIGIT_BASE + 65)
1219#define DTMF_SIGNAL_ANSWER_TONE (DTMF_TONE_DIGIT_BASE + 66)
1220#define DTMF_SIGNAL_REVERSED_ANSWER_TONE (DTMF_TONE_DIGIT_BASE + 67)
1221#define DTMF_SIGNAL_ANSAM_TONE (DTMF_TONE_DIGIT_BASE + 68)
1222#define DTMF_SIGNAL_REVERSED_ANSAM_TONE (DTMF_TONE_DIGIT_BASE + 69)
1223#define DTMF_SIGNAL_BELL103_ANSWER_TONE (DTMF_TONE_DIGIT_BASE + 70)
1224#define DTMF_SIGNAL_FAX_FLAGS (DTMF_TONE_DIGIT_BASE + 71)
1225#define DTMF_SIGNAL_G2_FAX_GROUP_ID (DTMF_TONE_DIGIT_BASE + 72)
1226#define DTMF_SIGNAL_HUMAN_SPEECH (DTMF_TONE_DIGIT_BASE + 73)
1227#define DTMF_SIGNAL_ANSWERING_MACHINE_390 (DTMF_TONE_DIGIT_BASE + 74)
1228
1229#define DTMF_MF_LISTEN_ACTIVE_FLAG 0x02
1230#define DTMF_SEND_MF_FLAG 0x02
1231#define DTMF_TONE_LISTEN_ACTIVE_FLAG 0x04
1232#define DTMF_SEND_TONE_FLAG 0x04
1233
1234#define PRIVATE_DTMF_TONE 5
1235
1236
1237/*------------------------------------------------------------------*/
1238/* FAX paper format extension */
1239/*------------------------------------------------------------------*/
1240
1241
1242#define PRIVATE_FAX_PAPER_FORMATS 6
1243
1244
1245
1246/*------------------------------------------------------------------*/
1247/* V.OWN extension */
1248/*------------------------------------------------------------------*/
1249
1250
1251#define PRIVATE_VOWN 7
1252
1253
1254
1255/*------------------------------------------------------------------*/
1256/* FAX non-standard facilities extension */
1257/*------------------------------------------------------------------*/
1258
1259
1260#define PRIVATE_FAX_NONSTANDARD 8
1261
1262
1263
1264/*------------------------------------------------------------------*/
1265/* Advanced voice */
1266/*------------------------------------------------------------------*/
1267
1268#define ADV_VOICE_WRITE_ACTIVATION 0
1269#define ADV_VOICE_WRITE_DEACTIVATION 1
1270#define ADV_VOICE_WRITE_UPDATE 2
1271
1272#define ADV_VOICE_OLD_COEF_COUNT 6
1273#define ADV_VOICE_NEW_COEF_BASE (ADV_VOICE_OLD_COEF_COUNT * sizeof(word))
1274
1275/*------------------------------------------------------------------*/
1276/* B1 resource switching */
1277/*------------------------------------------------------------------*/
1278
1279#define B1_FACILITY_LOCAL 0x01
1280#define B1_FACILITY_MIXER 0x02
1281#define B1_FACILITY_DTMFX 0x04
1282#define B1_FACILITY_DTMFR 0x08
1283#define B1_FACILITY_VOICE 0x10
1284#define B1_FACILITY_EC 0x20
1285
1286#define ADJUST_B_MODE_SAVE 0x0001
1287#define ADJUST_B_MODE_REMOVE_L23 0x0002
1288#define ADJUST_B_MODE_SWITCH_L1 0x0004
1289#define ADJUST_B_MODE_NO_RESOURCE 0x0008
1290#define ADJUST_B_MODE_ASSIGN_L23 0x0010
1291#define ADJUST_B_MODE_USER_CONNECT 0x0020
1292#define ADJUST_B_MODE_CONNECT 0x0040
1293#define ADJUST_B_MODE_RESTORE 0x0080
1294
1295#define ADJUST_B_START 0
1296#define ADJUST_B_SAVE_MIXER_1 1
1297#define ADJUST_B_SAVE_DTMF_1 2
1298#define ADJUST_B_REMOVE_L23_1 3
1299#define ADJUST_B_REMOVE_L23_2 4
1300#define ADJUST_B_SAVE_EC_1 5
1301#define ADJUST_B_SAVE_DTMF_PARAMETER_1 6
1302#define ADJUST_B_SAVE_VOICE_1 7
1303#define ADJUST_B_SWITCH_L1_1 8
1304#define ADJUST_B_SWITCH_L1_2 9
1305#define ADJUST_B_RESTORE_VOICE_1 10
1306#define ADJUST_B_RESTORE_VOICE_2 11
1307#define ADJUST_B_RESTORE_DTMF_PARAMETER_1 12
1308#define ADJUST_B_RESTORE_DTMF_PARAMETER_2 13
1309#define ADJUST_B_RESTORE_EC_1 14
1310#define ADJUST_B_RESTORE_EC_2 15
1311#define ADJUST_B_ASSIGN_L23_1 16
1312#define ADJUST_B_ASSIGN_L23_2 17
1313#define ADJUST_B_CONNECT_1 18
1314#define ADJUST_B_CONNECT_2 19
1315#define ADJUST_B_CONNECT_3 20
1316#define ADJUST_B_CONNECT_4 21
1317#define ADJUST_B_RESTORE_DTMF_1 22
1318#define ADJUST_B_RESTORE_DTMF_2 23
1319#define ADJUST_B_RESTORE_MIXER_1 24
1320#define ADJUST_B_RESTORE_MIXER_2 25
1321#define ADJUST_B_RESTORE_MIXER_3 26
1322#define ADJUST_B_RESTORE_MIXER_4 27
1323#define ADJUST_B_RESTORE_MIXER_5 28
1324#define ADJUST_B_RESTORE_MIXER_6 29
1325#define ADJUST_B_RESTORE_MIXER_7 30
1326#define ADJUST_B_END 31
1327
1328/*------------------------------------------------------------------*/
1329/* XON Protocol def's */
1330/*------------------------------------------------------------------*/
1331#define N_CH_XOFF 0x01
1332#define N_XON_SENT 0x02
1333#define N_XON_REQ 0x04
1334#define N_XON_CONNECT_IND 0x08
1335#define N_RX_FLOW_CONTROL_MASK 0x3f
1336#define N_OK_FC_PENDING 0x80
1337#define N_TX_FLOW_CONTROL_MASK 0xc0
1338
1339/*------------------------------------------------------------------*/
1340/* NCPI state */
1341/*------------------------------------------------------------------*/
1342#define NCPI_VALID_CONNECT_B3_IND 0x01
1343#define NCPI_VALID_CONNECT_B3_ACT 0x02
1344#define NCPI_VALID_DISC_B3_IND 0x04
1345#define NCPI_CONNECT_B3_ACT_SENT 0x08
1346#define NCPI_NEGOTIATE_B3_SENT 0x10
1347#define NCPI_MDM_CTS_ON_RECEIVED 0x40
1348#define NCPI_MDM_DCD_ON_RECEIVED 0x80
1349
1350/*------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
deleted file mode 100644
index 5a95587b3117..000000000000
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ /dev/null
@@ -1,239 +0,0 @@
1/* $Id: divamnt.c,v 1.32.6.10 2005/02/11 19:40:25 armin Exp $
2 *
3 * Driver for Eicon DIVA Server ISDN cards.
4 * Maint module
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/poll.h>
17#include <linux/mutex.h>
18#include <linux/uaccess.h>
19
20#include "platform.h"
21#include "di_defs.h"
22#include "divasync.h"
23#include "debug_if.h"
24
25static DEFINE_MUTEX(maint_mutex);
26static char *main_revision = "$Revision: 1.32.6.10 $";
27
28static int major;
29
30MODULE_DESCRIPTION("Maint driver for Eicon DIVA Server cards");
31MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
32MODULE_SUPPORTED_DEVICE("DIVA card driver");
33MODULE_LICENSE("GPL");
34
35static int buffer_length = 128;
36module_param(buffer_length, int, 0);
37static unsigned long diva_dbg_mem = 0;
38module_param(diva_dbg_mem, ulong, 0);
39
40static char *DRIVERNAME =
41 "Eicon DIVA - MAINT module (http://www.melware.net)";
42static char *DRIVERLNAME = "diva_mnt";
43static char *DEVNAME = "DivasMAINT";
44char *DRIVERRELEASE_MNT = "2.0";
45
46static wait_queue_head_t msgwaitq;
47static unsigned long opened;
48
49extern int mntfunc_init(int *, void **, unsigned long);
50extern void mntfunc_finit(void);
51extern int maint_read_write(void __user *buf, int count);
52
53/*
54 * helper functions
55 */
56static char *getrev(const char *revision)
57{
58 char *rev;
59 char *p;
60
61 if ((p = strchr(revision, ':'))) {
62 rev = p + 2;
63 p = strchr(rev, '$');
64 *--p = 0;
65 } else
66 rev = "1.0";
67
68 return rev;
69}
70
71/*
72 * kernel/user space copy functions
73 */
74int diva_os_copy_to_user(void *os_handle, void __user *dst, const void *src,
75 int length)
76{
77 return (copy_to_user(dst, src, length));
78}
79int diva_os_copy_from_user(void *os_handle, void *dst, const void __user *src,
80 int length)
81{
82 return (copy_from_user(dst, src, length));
83}
84
85/*
86 * get time
87 */
88void diva_os_get_time(dword *sec, dword *usec)
89{
90 struct timespec64 time;
91
92 ktime_get_ts64(&time);
93
94 *sec = (dword) time.tv_sec;
95 *usec = (dword) (time.tv_nsec / NSEC_PER_USEC);
96}
97
98/*
99 * device node operations
100 */
101static __poll_t maint_poll(struct file *file, poll_table *wait)
102{
103 __poll_t mask = 0;
104
105 poll_wait(file, &msgwaitq, wait);
106 mask = EPOLLOUT | EPOLLWRNORM;
107 if (file->private_data || diva_dbg_q_length()) {
108 mask |= EPOLLIN | EPOLLRDNORM;
109 }
110 return (mask);
111}
112
113static int maint_open(struct inode *ino, struct file *filep)
114{
115 int ret;
116
117 mutex_lock(&maint_mutex);
118 /* only one open is allowed, so we test
119 it atomically */
120 if (test_and_set_bit(0, &opened))
121 ret = -EBUSY;
122 else {
123 filep->private_data = NULL;
124 ret = nonseekable_open(ino, filep);
125 }
126 mutex_unlock(&maint_mutex);
127 return ret;
128}
129
130static int maint_close(struct inode *ino, struct file *filep)
131{
132 if (filep->private_data) {
133 diva_os_free(0, filep->private_data);
134 filep->private_data = NULL;
135 }
136
137 /* clear 'used' flag */
138 clear_bit(0, &opened);
139
140 return (0);
141}
142
143static ssize_t divas_maint_write(struct file *file, const char __user *buf,
144 size_t count, loff_t *ppos)
145{
146 return (maint_read_write((char __user *) buf, (int) count));
147}
148
149static ssize_t divas_maint_read(struct file *file, char __user *buf,
150 size_t count, loff_t *ppos)
151{
152 return (maint_read_write(buf, (int) count));
153}
154
155static const struct file_operations divas_maint_fops = {
156 .owner = THIS_MODULE,
157 .llseek = no_llseek,
158 .read = divas_maint_read,
159 .write = divas_maint_write,
160 .poll = maint_poll,
161 .open = maint_open,
162 .release = maint_close
163};
164
165static void divas_maint_unregister_chrdev(void)
166{
167 unregister_chrdev(major, DEVNAME);
168}
169
170static int __init divas_maint_register_chrdev(void)
171{
172 if ((major = register_chrdev(0, DEVNAME, &divas_maint_fops)) < 0)
173 {
174 printk(KERN_ERR "%s: failed to create /dev entry.\n",
175 DRIVERLNAME);
176 return (0);
177 }
178
179 return (1);
180}
181
182/*
183 * wake up reader
184 */
185void diva_maint_wakeup_read(void)
186{
187 wake_up_interruptible(&msgwaitq);
188}
189
190/*
191 * Driver Load
192 */
193static int __init maint_init(void)
194{
195 char tmprev[50];
196 int ret = 0;
197 void *buffer = NULL;
198
199 init_waitqueue_head(&msgwaitq);
200
201 printk(KERN_INFO "%s\n", DRIVERNAME);
202 printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_MNT);
203 strcpy(tmprev, main_revision);
204 printk("%s Build: %s \n", getrev(tmprev), DIVA_BUILD);
205
206 if (!divas_maint_register_chrdev()) {
207 ret = -EIO;
208 goto out;
209 }
210
211 if (!(mntfunc_init(&buffer_length, &buffer, diva_dbg_mem))) {
212 printk(KERN_ERR "%s: failed to connect to DIDD.\n",
213 DRIVERLNAME);
214 divas_maint_unregister_chrdev();
215 ret = -EIO;
216 goto out;
217 }
218
219 printk(KERN_INFO "%s: trace buffer = %p - %d kBytes, %s (Major: %d)\n",
220 DRIVERLNAME, buffer, (buffer_length / 1024),
221 (diva_dbg_mem == 0) ? "internal" : "external", major);
222
223out:
224 return (ret);
225}
226
227/*
228** Driver Unload
229*/
230static void __exit maint_exit(void)
231{
232 divas_maint_unregister_chrdev();
233 mntfunc_finit();
234
235 printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
236}
237
238module_init(maint_init);
239module_exit(maint_exit);
diff --git a/drivers/isdn/hardware/eicon/divasfunc.c b/drivers/isdn/hardware/eicon/divasfunc.c
deleted file mode 100644
index 4be5f8814777..000000000000
--- a/drivers/isdn/hardware/eicon/divasfunc.c
+++ /dev/null
@@ -1,237 +0,0 @@
1/* $Id: divasfunc.c,v 1.23.4.2 2004/08/28 20:03:53 armin Exp $
2 *
3 * Low level driver for Eicon DIVA Server ISDN cards.
4 *
5 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
6 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
10 */
11
12#include "platform.h"
13#include "di_defs.h"
14#include "pc.h"
15#include "di.h"
16#include "io.h"
17#include "divasync.h"
18#include "diva.h"
19#include "xdi_vers.h"
20
21#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
22#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
23
24static int debugmask;
25
26extern void DIVA_DIDD_Read(void *, int);
27
28extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
29
30extern char *DRIVERRELEASE_DIVAS;
31
32static dword notify_handle;
33static DESCRIPTOR DAdapter;
34static DESCRIPTOR MAdapter;
35
36/* --------------------------------------------------------------------------
37 MAINT driver connector section
38 -------------------------------------------------------------------------- */
39static void no_printf(unsigned char *x, ...)
40{
41 /* dummy debug function */
42}
43
44#include "debuglib.c"
45
46/*
47 * get the adapters serial number
48 */
49void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf)
50{
51 int contr = 0;
52
53 if ((contr = ((IoAdapter->serialNo & 0xff000000) >> 24))) {
54 sprintf(buf, "%d-%d",
55 IoAdapter->serialNo & 0x00ffffff, contr + 1);
56 } else {
57 sprintf(buf, "%d", IoAdapter->serialNo);
58 }
59}
60
61/*
62 * register a new adapter
63 */
64void diva_xdi_didd_register_adapter(int card)
65{
66 DESCRIPTOR d;
67 IDI_SYNC_REQ req;
68
69 if (card && ((card - 1) < MAX_ADAPTER) &&
70 IoAdapters[card - 1] && Requests[card - 1]) {
71 d.type = IoAdapters[card - 1]->Properties.DescType;
72 d.request = Requests[card - 1];
73 d.channels = IoAdapters[card - 1]->Properties.Channels;
74 d.features = IoAdapters[card - 1]->Properties.Features;
75 DBG_TRC(("DIDD register A(%d) channels=%d", card,
76 d.channels))
77 /* workaround for different Name in structure */
78 strlcpy(IoAdapters[card - 1]->Name,
79 IoAdapters[card - 1]->Properties.Name,
80 sizeof(IoAdapters[card - 1]->Name));
81 req.didd_remove_adapter.e.Req = 0;
82 req.didd_add_adapter.e.Rc = IDI_SYNC_REQ_DIDD_ADD_ADAPTER;
83 req.didd_add_adapter.info.descriptor = (void *) &d;
84 DAdapter.request((ENTITY *)&req);
85 if (req.didd_add_adapter.e.Rc != 0xff) {
86 DBG_ERR(("DIDD register A(%d) failed !", card))
87 }
88 IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
89 }
90}
91
92/*
93 * remove an adapter
94 */
95void diva_xdi_didd_remove_adapter(int card)
96{
97 IDI_SYNC_REQ req;
98 ADAPTER *a = &IoAdapters[card - 1]->a;
99
100 IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
101 DBG_TRC(("DIDD de-register A(%d)", card))
102 req.didd_remove_adapter.e.Req = 0;
103 req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER;
104 req.didd_remove_adapter.info.p_request =
105 (IDI_CALL) Requests[card - 1];
106 DAdapter.request((ENTITY *)&req);
107 memset(&(a->IdTable), 0x00, 256);
108}
109
110/*
111 * start debug
112 */
113static void start_dbg(void)
114{
115 DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
116 DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s])",
117 DIVA_BUILD, diva_xdi_common_code_build))
118 }
119
120/*
121 * stop debug
122 */
123static void stop_dbg(void)
124{
125 DbgDeregister();
126 memset(&MAdapter, 0, sizeof(MAdapter));
127 dprintf = no_printf;
128}
129
130/*
131 * didd callback function
132 */
133static void *didd_callback(void *context, DESCRIPTOR *adapter,
134 int removal)
135{
136 if (adapter->type == IDI_DADAPTER) {
137 DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
138 return (NULL);
139 }
140
141 if (adapter->type == IDI_DIMAINT) {
142 if (removal) {
143 stop_dbg();
144 } else {
145 memcpy(&MAdapter, adapter, sizeof(MAdapter));
146 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
147 start_dbg();
148 }
149 }
150 return (NULL);
151}
152
153/*
154 * connect to didd
155 */
156static int __init connect_didd(void)
157{
158 int x = 0;
159 int dadapter = 0;
160 IDI_SYNC_REQ req;
161 DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
162
163 DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
164
165 for (x = 0; x < MAX_DESCRIPTORS; x++) {
166 if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */
167 dadapter = 1;
168 memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
169 req.didd_notify.e.Req = 0;
170 req.didd_notify.e.Rc =
171 IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
172 req.didd_notify.info.callback = (void *)didd_callback;
173 req.didd_notify.info.context = NULL;
174 DAdapter.request((ENTITY *)&req);
175 if (req.didd_notify.e.Rc != 0xff) {
176 stop_dbg();
177 return (0);
178 }
179 notify_handle = req.didd_notify.info.handle;
180 } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
181 memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
182 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
183 start_dbg();
184 }
185 }
186
187 if (!dadapter) {
188 stop_dbg();
189 }
190
191 return (dadapter);
192}
193
194/*
195 * disconnect from didd
196 */
197static void disconnect_didd(void)
198{
199 IDI_SYNC_REQ req;
200
201 stop_dbg();
202
203 req.didd_notify.e.Req = 0;
204 req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
205 req.didd_notify.info.handle = notify_handle;
206 DAdapter.request((ENTITY *)&req);
207}
208
209/*
210 * init
211 */
212int __init divasfunc_init(int dbgmask)
213{
214 char *version;
215
216 debugmask = dbgmask;
217
218 if (!connect_didd()) {
219 DBG_ERR(("divasfunc: failed to connect to DIDD."))
220 return (0);
221 }
222
223 version = diva_xdi_common_code_build;
224
225 divasa_xdi_driver_entry();
226
227 return (1);
228}
229
230/*
231 * exit
232 */
233void divasfunc_exit(void)
234{
235 divasa_xdi_driver_unload();
236 disconnect_didd();
237}
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
deleted file mode 100644
index e7081e0c0e35..000000000000
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ /dev/null
@@ -1,562 +0,0 @@
1/* $Id: divasi.c,v 1.25.6.2 2005/01/31 12:22:20 armin Exp $
2 *
3 * Driver for Eicon DIVA Server ISDN cards.
4 * User Mode IDI Interface
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/poll.h>
18#include <linux/proc_fs.h>
19#include <linux/skbuff.h>
20#include <linux/seq_file.h>
21#include <linux/uaccess.h>
22
23#include "platform.h"
24#include "di_defs.h"
25#include "divasync.h"
26#include "um_xdi.h"
27#include "um_idi.h"
28
29static char *main_revision = "$Revision: 1.25.6.2 $";
30
31static int major;
32
33MODULE_DESCRIPTION("User IDI Interface for Eicon ISDN cards");
34MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
35MODULE_SUPPORTED_DEVICE("DIVA card driver");
36MODULE_LICENSE("GPL");
37
38typedef struct _diva_um_idi_os_context {
39 wait_queue_head_t read_wait;
40 wait_queue_head_t close_wait;
41 struct timer_list diva_timer_id;
42 int aborted;
43 int adapter_nr;
44} diva_um_idi_os_context_t;
45
46static char *DRIVERNAME = "Eicon DIVA - User IDI (http://www.melware.net)";
47static char *DRIVERLNAME = "diva_idi";
48static char *DEVNAME = "DivasIDI";
49char *DRIVERRELEASE_IDI = "2.0";
50
51extern int idifunc_init(void);
52extern void idifunc_finit(void);
53
54/*
55 * helper functions
56 */
57static char *getrev(const char *revision)
58{
59 char *rev;
60 char *p;
61 if ((p = strchr(revision, ':'))) {
62 rev = p + 2;
63 p = strchr(rev, '$');
64 *--p = 0;
65 } else
66 rev = "1.0";
67 return rev;
68}
69
70/*
71 * LOCALS
72 */
73static ssize_t um_idi_read(struct file *file, char __user *buf, size_t count,
74 loff_t *offset);
75static ssize_t um_idi_write(struct file *file, const char __user *buf,
76 size_t count, loff_t *offset);
77static __poll_t um_idi_poll(struct file *file, poll_table *wait);
78static int um_idi_open(struct inode *inode, struct file *file);
79static int um_idi_release(struct inode *inode, struct file *file);
80static int remove_entity(void *entity);
81static void diva_um_timer_function(struct timer_list *t);
82
83/*
84 * proc entry
85 */
86extern struct proc_dir_entry *proc_net_eicon;
87static struct proc_dir_entry *um_idi_proc_entry = NULL;
88
89static int um_idi_proc_show(struct seq_file *m, void *v)
90{
91 char tmprev[32];
92
93 seq_printf(m, "%s\n", DRIVERNAME);
94 seq_printf(m, "name : %s\n", DRIVERLNAME);
95 seq_printf(m, "release : %s\n", DRIVERRELEASE_IDI);
96 strcpy(tmprev, main_revision);
97 seq_printf(m, "revision : %s\n", getrev(tmprev));
98 seq_printf(m, "build : %s\n", DIVA_BUILD);
99 seq_printf(m, "major : %d\n", major);
100
101 return 0;
102}
103
104static int __init create_um_idi_proc(void)
105{
106 um_idi_proc_entry = proc_create_single(DRIVERLNAME, S_IRUGO,
107 proc_net_eicon, um_idi_proc_show);
108 if (!um_idi_proc_entry)
109 return (0);
110 return (1);
111}
112
113static void remove_um_idi_proc(void)
114{
115 if (um_idi_proc_entry) {
116 remove_proc_entry(DRIVERLNAME, proc_net_eicon);
117 um_idi_proc_entry = NULL;
118 }
119}
120
121static const struct file_operations divas_idi_fops = {
122 .owner = THIS_MODULE,
123 .llseek = no_llseek,
124 .read = um_idi_read,
125 .write = um_idi_write,
126 .poll = um_idi_poll,
127 .open = um_idi_open,
128 .release = um_idi_release
129};
130
131static void divas_idi_unregister_chrdev(void)
132{
133 unregister_chrdev(major, DEVNAME);
134}
135
136static int __init divas_idi_register_chrdev(void)
137{
138 if ((major = register_chrdev(0, DEVNAME, &divas_idi_fops)) < 0)
139 {
140 printk(KERN_ERR "%s: failed to create /dev entry.\n",
141 DRIVERLNAME);
142 return (0);
143 }
144
145 return (1);
146}
147
148/*
149** Driver Load
150*/
151static int __init divasi_init(void)
152{
153 char tmprev[50];
154 int ret = 0;
155
156 printk(KERN_INFO "%s\n", DRIVERNAME);
157 printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_IDI);
158 strcpy(tmprev, main_revision);
159 printk("%s Build: %s\n", getrev(tmprev), DIVA_BUILD);
160
161 if (!divas_idi_register_chrdev()) {
162 ret = -EIO;
163 goto out;
164 }
165
166 if (!create_um_idi_proc()) {
167 divas_idi_unregister_chrdev();
168 printk(KERN_ERR "%s: failed to create proc entry.\n",
169 DRIVERLNAME);
170 ret = -EIO;
171 goto out;
172 }
173
174 if (!(idifunc_init())) {
175 remove_um_idi_proc();
176 divas_idi_unregister_chrdev();
177 printk(KERN_ERR "%s: failed to connect to DIDD.\n",
178 DRIVERLNAME);
179 ret = -EIO;
180 goto out;
181 }
182 printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
183
184out:
185 return (ret);
186}
187
188
189/*
190** Driver Unload
191*/
192static void __exit divasi_exit(void)
193{
194 idifunc_finit();
195 remove_um_idi_proc();
196 divas_idi_unregister_chrdev();
197
198 printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
199}
200
201module_init(divasi_init);
202module_exit(divasi_exit);
203
204
205/*
206 * FILE OPERATIONS
207 */
208
209static int
210divas_um_idi_copy_to_user(void *os_handle, void *dst, const void *src,
211 int length)
212{
213 memcpy(dst, src, length);
214 return (length);
215}
216
217static ssize_t
218um_idi_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
219{
220 diva_um_idi_os_context_t *p_os;
221 int ret = -EINVAL;
222 void *data;
223
224 if (!file->private_data) {
225 return (-ENODEV);
226 }
227
228 if (!
229 (p_os =
230 (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->
231 private_data)))
232 {
233 return (-ENODEV);
234 }
235 if (p_os->aborted) {
236 return (-ENODEV);
237 }
238
239 if (!(data = diva_os_malloc(0, count))) {
240 return (-ENOMEM);
241 }
242
243 ret = diva_um_idi_read(file->private_data,
244 file, data, count,
245 divas_um_idi_copy_to_user);
246 switch (ret) {
247 case 0: /* no message available */
248 ret = (-EAGAIN);
249 break;
250 case (-1): /* adapter was removed */
251 ret = (-ENODEV);
252 break;
253 case (-2): /* message_length > length of user buffer */
254 ret = (-EFAULT);
255 break;
256 }
257
258 if (ret > 0) {
259 if (copy_to_user(buf, data, ret)) {
260 ret = (-EFAULT);
261 }
262 }
263
264 diva_os_free(0, data);
265 DBG_TRC(("read: ret %d", ret));
266 return (ret);
267}
268
269
270static int
271divas_um_idi_copy_from_user(void *os_handle, void *dst, const void *src,
272 int length)
273{
274 memcpy(dst, src, length);
275 return (length);
276}
277
278static int um_idi_open_adapter(struct file *file, int adapter_nr)
279{
280 diva_um_idi_os_context_t *p_os;
281 void *e =
282 divas_um_idi_create_entity((dword) adapter_nr, (void *) file);
283
284 if (!(file->private_data = e)) {
285 return (0);
286 }
287 p_os = (diva_um_idi_os_context_t *) diva_um_id_get_os_context(e);
288 init_waitqueue_head(&p_os->read_wait);
289 init_waitqueue_head(&p_os->close_wait);
290 timer_setup(&p_os->diva_timer_id, diva_um_timer_function, 0);
291 p_os->aborted = 0;
292 p_os->adapter_nr = adapter_nr;
293 return (1);
294}
295
296static ssize_t
297um_idi_write(struct file *file, const char __user *buf, size_t count,
298 loff_t *offset)
299{
300 diva_um_idi_os_context_t *p_os;
301 int ret = -EINVAL;
302 void *data;
303 int adapter_nr = 0;
304
305 if (!file->private_data) {
306 /* the first write() selects the adapter_nr */
307 if (count == sizeof(int)) {
308 if (copy_from_user
309 ((void *) &adapter_nr, buf,
310 count)) return (-EFAULT);
311 if (!(um_idi_open_adapter(file, adapter_nr)))
312 return (-ENODEV);
313 return (count);
314 } else
315 return (-ENODEV);
316 }
317
318 if (!(p_os =
319 (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->
320 private_data)))
321 {
322 return (-ENODEV);
323 }
324 if (p_os->aborted) {
325 return (-ENODEV);
326 }
327
328 if (!(data = diva_os_malloc(0, count))) {
329 return (-ENOMEM);
330 }
331
332 if (copy_from_user(data, buf, count)) {
333 ret = -EFAULT;
334 } else {
335 ret = diva_um_idi_write(file->private_data,
336 file, data, count,
337 divas_um_idi_copy_from_user);
338 switch (ret) {
339 case 0: /* no space available */
340 ret = (-EAGAIN);
341 break;
342 case (-1): /* adapter was removed */
343 ret = (-ENODEV);
344 break;
345 case (-2): /* length of user buffer > max message_length */
346 ret = (-EFAULT);
347 break;
348 }
349 }
350 diva_os_free(0, data);
351 DBG_TRC(("write: ret %d", ret));
352 return (ret);
353}
354
355static __poll_t um_idi_poll(struct file *file, poll_table *wait)
356{
357 diva_um_idi_os_context_t *p_os;
358
359 if (!file->private_data) {
360 return (EPOLLERR);
361 }
362
363 if ((!(p_os =
364 (diva_um_idi_os_context_t *)
365 diva_um_id_get_os_context(file->private_data)))
366 || p_os->aborted) {
367 return (EPOLLERR);
368 }
369
370 poll_wait(file, &p_os->read_wait, wait);
371
372 if (p_os->aborted) {
373 return (EPOLLERR);
374 }
375
376 switch (diva_user_mode_idi_ind_ready(file->private_data, file)) {
377 case (-1):
378 return (EPOLLERR);
379
380 case 0:
381 return (0);
382 }
383
384 return (EPOLLIN | EPOLLRDNORM);
385}
386
387static int um_idi_open(struct inode *inode, struct file *file)
388{
389 return (0);
390}
391
392
393static int um_idi_release(struct inode *inode, struct file *file)
394{
395 diva_um_idi_os_context_t *p_os;
396 unsigned int adapter_nr;
397 int ret = 0;
398
399 if (!(file->private_data)) {
400 ret = -ENODEV;
401 goto out;
402 }
403
404 if (!(p_os =
405 (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) {
406 ret = -ENODEV;
407 goto out;
408 }
409
410 adapter_nr = p_os->adapter_nr;
411
412 if ((ret = remove_entity(file->private_data))) {
413 goto out;
414 }
415
416 if (divas_um_idi_delete_entity
417 ((int) adapter_nr, file->private_data)) {
418 ret = -ENODEV;
419 goto out;
420 }
421
422out:
423 return (ret);
424}
425
426int diva_os_get_context_size(void)
427{
428 return (sizeof(diva_um_idi_os_context_t));
429}
430
431void diva_os_wakeup_read(void *os_context)
432{
433 diva_um_idi_os_context_t *p_os =
434 (diva_um_idi_os_context_t *) os_context;
435 wake_up_interruptible(&p_os->read_wait);
436}
437
438void diva_os_wakeup_close(void *os_context)
439{
440 diva_um_idi_os_context_t *p_os =
441 (diva_um_idi_os_context_t *) os_context;
442 wake_up_interruptible(&p_os->close_wait);
443}
444
445static
446void diva_um_timer_function(struct timer_list *t)
447{
448 diva_um_idi_os_context_t *p_os = from_timer(p_os, t, diva_timer_id);
449
450 p_os->aborted = 1;
451 wake_up_interruptible(&p_os->read_wait);
452 wake_up_interruptible(&p_os->close_wait);
453 DBG_ERR(("entity removal watchdog"))
454 }
455
456/*
457** If application exits without entity removal this function will remove
458** entity and block until removal is complete
459*/
460static int remove_entity(void *entity)
461{
462 struct task_struct *curtask = current;
463 diva_um_idi_os_context_t *p_os;
464
465 diva_um_idi_stop_wdog(entity);
466
467 if (!entity) {
468 DBG_FTL(("Zero entity on remove"))
469 return (0);
470 }
471
472 if (!(p_os =
473 (diva_um_idi_os_context_t *)
474 diva_um_id_get_os_context(entity))) {
475 DBG_FTL(("Zero entity os context on remove"))
476 return (0);
477 }
478
479 if (!divas_um_idi_entity_assigned(entity) || p_os->aborted) {
480 /*
481 Entity is not assigned, also can be removed
482 */
483 return (0);
484 }
485
486 DBG_TRC(("E(%08x) check remove", entity))
487
488 /*
489 If adapter not answers on remove request inside of
490 10 Sec, then adapter is dead
491 */
492 diva_um_idi_start_wdog(entity);
493
494 {
495 DECLARE_WAITQUEUE(wait, curtask);
496
497 add_wait_queue(&p_os->close_wait, &wait);
498 for (;;) {
499 set_current_state(TASK_INTERRUPTIBLE);
500 if (!divas_um_idi_entity_start_remove(entity)
501 || p_os->aborted) {
502 break;
503 }
504 schedule();
505 }
506 set_current_state(TASK_RUNNING);
507 remove_wait_queue(&p_os->close_wait, &wait);
508 }
509
510 DBG_TRC(("E(%08x) start remove", entity))
511 {
512 DECLARE_WAITQUEUE(wait, curtask);
513
514 add_wait_queue(&p_os->close_wait, &wait);
515 for (;;) {
516 set_current_state(TASK_INTERRUPTIBLE);
517 if (!divas_um_idi_entity_assigned(entity)
518 || p_os->aborted) {
519 break;
520 }
521 schedule();
522 }
523 set_current_state(TASK_RUNNING);
524 remove_wait_queue(&p_os->close_wait, &wait);
525 }
526
527 DBG_TRC(("E(%08x) remove complete, aborted:%d", entity,
528 p_os->aborted))
529
530 diva_um_idi_stop_wdog(entity);
531
532 p_os->aborted = 0;
533
534 return (0);
535}
536
537/*
538 * timer watchdog
539 */
540void diva_um_idi_start_wdog(void *entity)
541{
542 diva_um_idi_os_context_t *p_os;
543
544 if (entity &&
545 ((p_os =
546 (diva_um_idi_os_context_t *)
547 diva_um_id_get_os_context(entity)))) {
548 mod_timer(&p_os->diva_timer_id, jiffies + 10 * HZ);
549 }
550}
551
552void diva_um_idi_stop_wdog(void *entity)
553{
554 diva_um_idi_os_context_t *p_os;
555
556 if (entity &&
557 ((p_os =
558 (diva_um_idi_os_context_t *)
559 diva_um_id_get_os_context(entity)))) {
560 del_timer(&p_os->diva_timer_id);
561 }
562}
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
deleted file mode 100644
index b6a3950b2564..000000000000
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ /dev/null
@@ -1,848 +0,0 @@
1/* $Id: divasmain.c,v 1.55.4.6 2005/02/09 19:28:20 armin Exp $
2 *
3 * Low level driver for Eicon DIVA Server ISDN cards.
4 *
5 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
6 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/uaccess.h>
16#include <asm/io.h>
17#include <linux/ioport.h>
18#include <linux/pci.h>
19#include <linux/interrupt.h>
20#include <linux/list.h>
21#include <linux/poll.h>
22#include <linux/kmod.h>
23
24#include "platform.h"
25#undef ID_MASK
26#undef N_DATA
27#include "pc.h"
28#include "di_defs.h"
29#include "divasync.h"
30#include "diva.h"
31#include "di.h"
32#include "io.h"
33#include "xdi_msg.h"
34#include "xdi_adapter.h"
35#include "xdi_vers.h"
36#include "diva_dma.h"
37#include "diva_pci.h"
38
39static char *main_revision = "$Revision: 1.55.4.6 $";
40
41static int major;
42
43static int dbgmask;
44
45MODULE_DESCRIPTION("Kernel driver for Eicon DIVA Server cards");
46MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
47MODULE_LICENSE("GPL");
48
49module_param(dbgmask, int, 0);
50MODULE_PARM_DESC(dbgmask, "initial debug mask");
51
52static char *DRIVERNAME =
53 "Eicon DIVA Server driver (http://www.melware.net)";
54static char *DRIVERLNAME = "divas";
55static char *DEVNAME = "Divas";
56char *DRIVERRELEASE_DIVAS = "2.0";
57
58extern irqreturn_t diva_os_irq_wrapper(int irq, void *context);
59extern int create_divas_proc(void);
60extern void remove_divas_proc(void);
61extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf);
62extern int divasfunc_init(int dbgmask);
63extern void divasfunc_exit(void);
64
65typedef struct _diva_os_thread_dpc {
66 struct tasklet_struct divas_task;
67 diva_os_soft_isr_t *psoft_isr;
68} diva_os_thread_dpc_t;
69
70/* --------------------------------------------------------------------------
71 PCI driver interface section
72 -------------------------------------------------------------------------- */
73/*
74 vendor, device Vendor and device ID to match (or PCI_ANY_ID)
75 subvendor, Subsystem vendor and device ID to match (or PCI_ANY_ID)
76 subdevice
77 class, Device class to match. The class_mask tells which bits
78 class_mask of the class are honored during the comparison.
79 driver_data Data private to the driver.
80*/
81
82#if !defined(PCI_DEVICE_ID_EICON_MAESTRAP_2)
83#define PCI_DEVICE_ID_EICON_MAESTRAP_2 0xE015
84#endif
85
86#if !defined(PCI_DEVICE_ID_EICON_4BRI_VOIP)
87#define PCI_DEVICE_ID_EICON_4BRI_VOIP 0xE016
88#endif
89
90#if !defined(PCI_DEVICE_ID_EICON_4BRI_2_VOIP)
91#define PCI_DEVICE_ID_EICON_4BRI_2_VOIP 0xE017
92#endif
93
94#if !defined(PCI_DEVICE_ID_EICON_BRI2M_2)
95#define PCI_DEVICE_ID_EICON_BRI2M_2 0xE018
96#endif
97
98#if !defined(PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP)
99#define PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP 0xE019
100#endif
101
102#if !defined(PCI_DEVICE_ID_EICON_2F)
103#define PCI_DEVICE_ID_EICON_2F 0xE01A
104#endif
105
106#if !defined(PCI_DEVICE_ID_EICON_BRI2M_2_VOIP)
107#define PCI_DEVICE_ID_EICON_BRI2M_2_VOIP 0xE01B
108#endif
109
110/*
111 This table should be sorted by PCI device ID
112*/
113static const struct pci_device_id divas_pci_tbl[] = {
114 /* Diva Server BRI-2M PCI 0xE010 */
115 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRA),
116 CARDTYPE_MAESTRA_PCI },
117 /* Diva Server 4BRI-8M PCI 0xE012 */
118 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ),
119 CARDTYPE_DIVASRV_Q_8M_PCI },
120 /* Diva Server 4BRI-8M 2.0 PCI 0xE013 */
121 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ_U),
122 CARDTYPE_DIVASRV_Q_8M_V2_PCI },
123 /* Diva Server PRI-30M PCI 0xE014 */
124 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP),
125 CARDTYPE_DIVASRV_P_30M_PCI },
126 /* Diva Server PRI 2.0 adapter 0xE015 */
127 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2),
128 CARDTYPE_DIVASRV_P_30M_V2_PCI },
129 /* Diva Server Voice 4BRI-8M PCI 0xE016 */
130 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_VOIP),
131 CARDTYPE_DIVASRV_VOICE_Q_8M_PCI },
132 /* Diva Server Voice 4BRI-8M 2.0 PCI 0xE017 */
133 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_2_VOIP),
134 CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI },
135 /* Diva Server BRI-2M 2.0 PCI 0xE018 */
136 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2),
137 CARDTYPE_DIVASRV_B_2M_V2_PCI },
138 /* Diva Server Voice PRI 2.0 PCI 0xE019 */
139 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP),
140 CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI },
141 /* Diva Server 2FX 0xE01A */
142 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_2F),
143 CARDTYPE_DIVASRV_B_2F_PCI },
144 /* Diva Server Voice BRI-2M 2.0 PCI 0xE01B */
145 { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2_VOIP),
146 CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI },
147 { 0, } /* 0 terminated list. */
148};
149MODULE_DEVICE_TABLE(pci, divas_pci_tbl);
150
151static int divas_init_one(struct pci_dev *pdev,
152 const struct pci_device_id *ent);
153static void divas_remove_one(struct pci_dev *pdev);
154
155static struct pci_driver diva_pci_driver = {
156 .name = "divas",
157 .probe = divas_init_one,
158 .remove = divas_remove_one,
159 .id_table = divas_pci_tbl,
160};
161
162/*********************************************************
163 ** little helper functions
164 *********************************************************/
165static char *getrev(const char *revision)
166{
167 char *rev;
168 char *p;
169 if ((p = strchr(revision, ':'))) {
170 rev = p + 2;
171 p = strchr(rev, '$');
172 *--p = 0;
173 } else
174 rev = "1.0";
175 return rev;
176}
177
178void diva_log_info(unsigned char *format, ...)
179{
180 va_list args;
181 unsigned char line[160];
182
183 va_start(args, format);
184 vsnprintf(line, sizeof(line), format, args);
185 va_end(args);
186
187 printk(KERN_INFO "%s: %s\n", DRIVERLNAME, line);
188}
189
190void divas_get_version(char *p)
191{
192 char tmprev[32];
193
194 strcpy(tmprev, main_revision);
195 sprintf(p, "%s: %s(%s) %s(%s) major=%d\n", DRIVERLNAME, DRIVERRELEASE_DIVAS,
196 getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD, major);
197}
198
199/* --------------------------------------------------------------------------
200 PCI Bus services
201 -------------------------------------------------------------------------- */
202byte diva_os_get_pci_bus(void *pci_dev_handle)
203{
204 struct pci_dev *pdev = (struct pci_dev *) pci_dev_handle;
205 return ((byte) pdev->bus->number);
206}
207
208byte diva_os_get_pci_func(void *pci_dev_handle)
209{
210 struct pci_dev *pdev = (struct pci_dev *) pci_dev_handle;
211 return ((byte) pdev->devfn);
212}
213
214unsigned long divasa_get_pci_irq(unsigned char bus, unsigned char func,
215 void *pci_dev_handle)
216{
217 unsigned char irq = 0;
218 struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
219
220 irq = dev->irq;
221
222 return ((unsigned long) irq);
223}
224
225unsigned long divasa_get_pci_bar(unsigned char bus, unsigned char func,
226 int bar, void *pci_dev_handle)
227{
228 unsigned long ret = 0;
229 struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
230
231 if (bar < 6) {
232 ret = dev->resource[bar].start;
233 }
234
235 DBG_TRC(("GOT BAR[%d]=%08x", bar, ret));
236
237 {
238 unsigned long type = (ret & 0x00000001);
239 if (type & PCI_BASE_ADDRESS_SPACE_IO) {
240 DBG_TRC((" I/O"));
241 ret &= PCI_BASE_ADDRESS_IO_MASK;
242 } else {
243 DBG_TRC((" memory"));
244 ret &= PCI_BASE_ADDRESS_MEM_MASK;
245 }
246 DBG_TRC((" final=%08x", ret));
247 }
248
249 return (ret);
250}
251
252void PCIwrite(byte bus, byte func, int offset, void *data, int length,
253 void *pci_dev_handle)
254{
255 struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
256
257 switch (length) {
258 case 1: /* byte */
259 pci_write_config_byte(dev, offset,
260 *(unsigned char *) data);
261 break;
262 case 2: /* word */
263 pci_write_config_word(dev, offset,
264 *(unsigned short *) data);
265 break;
266 case 4: /* dword */
267 pci_write_config_dword(dev, offset,
268 *(unsigned int *) data);
269 break;
270
271 default: /* buffer */
272 if (!(length % 4) && !(length & 0x03)) { /* Copy as dword */
273 dword *p = (dword *) data;
274 length /= 4;
275
276 while (length--) {
277 pci_write_config_dword(dev, offset,
278 *(unsigned int *)
279 p++);
280 }
281 } else { /* copy as byte stream */
282 byte *p = (byte *) data;
283
284 while (length--) {
285 pci_write_config_byte(dev, offset,
286 *(unsigned char *)
287 p++);
288 }
289 }
290 }
291}
292
293void PCIread(byte bus, byte func, int offset, void *data, int length,
294 void *pci_dev_handle)
295{
296 struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
297
298 switch (length) {
299 case 1: /* byte */
300 pci_read_config_byte(dev, offset, (unsigned char *) data);
301 break;
302 case 2: /* word */
303 pci_read_config_word(dev, offset, (unsigned short *) data);
304 break;
305 case 4: /* dword */
306 pci_read_config_dword(dev, offset, (unsigned int *) data);
307 break;
308
309 default: /* buffer */
310 if (!(length % 4) && !(length & 0x03)) { /* Copy as dword */
311 dword *p = (dword *) data;
312 length /= 4;
313
314 while (length--) {
315 pci_read_config_dword(dev, offset,
316 (unsigned int *)
317 p++);
318 }
319 } else { /* copy as byte stream */
320 byte *p = (byte *) data;
321
322 while (length--) {
323 pci_read_config_byte(dev, offset,
324 (unsigned char *)
325 p++);
326 }
327 }
328 }
329}
330
331/*
332 Init map with DMA pages. It is not problem if some allocations fail -
333 the channels that will not get one DMA page will use standard PIO
334 interface
335*/
336static void *diva_pci_alloc_consistent(struct pci_dev *hwdev,
337 size_t size,
338 dma_addr_t *dma_handle,
339 void **addr_handle)
340{
341 void *addr = pci_alloc_consistent(hwdev, size, dma_handle);
342
343 *addr_handle = addr;
344
345 return (addr);
346}
347
348void diva_init_dma_map(void *hdev,
349 struct _diva_dma_map_entry **ppmap, int nentries)
350{
351 struct pci_dev *pdev = (struct pci_dev *) hdev;
352 struct _diva_dma_map_entry *pmap =
353 diva_alloc_dma_map(hdev, nentries);
354
355 if (pmap) {
356 int i;
357 dma_addr_t dma_handle;
358 void *cpu_addr;
359 void *addr_handle;
360
361 for (i = 0; i < nentries; i++) {
362 if (!(cpu_addr = diva_pci_alloc_consistent(pdev,
363 PAGE_SIZE,
364 &dma_handle,
365 &addr_handle)))
366 {
367 break;
368 }
369 diva_init_dma_map_entry(pmap, i, cpu_addr,
370 (dword) dma_handle,
371 addr_handle);
372 DBG_TRC(("dma map alloc [%d]=(%08lx:%08x:%08lx)",
373 i, (unsigned long) cpu_addr,
374 (dword) dma_handle,
375 (unsigned long) addr_handle))}
376 }
377
378 *ppmap = pmap;
379}
380
381/*
382 Free all contained in the map entries and memory used by the map
383 Should be always called after adapter removal from DIDD array
384*/
385void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap)
386{
387 struct pci_dev *pdev = (struct pci_dev *) hdev;
388 int i;
389 dword phys_addr;
390 void *cpu_addr;
391 dma_addr_t dma_handle;
392 void *addr_handle;
393
394 for (i = 0; (pmap != NULL); i++) {
395 diva_get_dma_map_entry(pmap, i, &cpu_addr, &phys_addr);
396 if (!cpu_addr) {
397 break;
398 }
399 addr_handle = diva_get_entry_handle(pmap, i);
400 dma_handle = (dma_addr_t) phys_addr;
401 pci_free_consistent(pdev, PAGE_SIZE, addr_handle,
402 dma_handle);
403 DBG_TRC(("dma map free [%d]=(%08lx:%08x:%08lx)", i,
404 (unsigned long) cpu_addr, (dword) dma_handle,
405 (unsigned long) addr_handle))
406 }
407
408 diva_free_dma_mapping(pmap);
409}
410
411
412/*********************************************************
413 ** I/O port utilities
414 *********************************************************/
415
416int
417diva_os_register_io_port(void *adapter, int on, unsigned long port,
418 unsigned long length, const char *name, int id)
419{
420 if (on) {
421 if (!request_region(port, length, name)) {
422 DBG_ERR(("A: I/O: can't register port=%08x", port))
423 return (-1);
424 }
425 } else {
426 release_region(port, length);
427 }
428 return (0);
429}
430
431void __iomem *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a, int id, unsigned long bar, unsigned long area_length)
432{
433 void __iomem *ret = ioremap(bar, area_length);
434 DBG_TRC(("remap(%08x)->%p", bar, ret));
435 return (ret);
436}
437
438void divasa_unmap_pci_bar(void __iomem *bar)
439{
440 if (bar) {
441 iounmap(bar);
442 }
443}
444
445/*********************************************************
446 ** I/O port access
447 *********************************************************/
448inline byte inpp(void __iomem *addr)
449{
450 return (inb((unsigned long) addr));
451}
452
453inline word inppw(void __iomem *addr)
454{
455 return (inw((unsigned long) addr));
456}
457
458inline void inppw_buffer(void __iomem *addr, void *P, int length)
459{
460 insw((unsigned long) addr, (word *) P, length >> 1);
461}
462
463inline void outppw_buffer(void __iomem *addr, void *P, int length)
464{
465 outsw((unsigned long) addr, (word *) P, length >> 1);
466}
467
468inline void outppw(void __iomem *addr, word w)
469{
470 outw(w, (unsigned long) addr);
471}
472
473inline void outpp(void __iomem *addr, word p)
474{
475 outb(p, (unsigned long) addr);
476}
477
478/* --------------------------------------------------------------------------
479 IRQ request / remove
480 -------------------------------------------------------------------------- */
481int diva_os_register_irq(void *context, byte irq, const char *name)
482{
483 int result = request_irq(irq, diva_os_irq_wrapper,
484 IRQF_SHARED, name, context);
485 return (result);
486}
487
488void diva_os_remove_irq(void *context, byte irq)
489{
490 free_irq(irq, context);
491}
492
493/* --------------------------------------------------------------------------
494 DPC framework implementation
495 -------------------------------------------------------------------------- */
496static void diva_os_dpc_proc(unsigned long context)
497{
498 diva_os_thread_dpc_t *psoft_isr = (diva_os_thread_dpc_t *) context;
499 diva_os_soft_isr_t *pisr = psoft_isr->psoft_isr;
500
501 (*(pisr->callback)) (pisr, pisr->callback_context);
502}
503
504int diva_os_initialize_soft_isr(diva_os_soft_isr_t *psoft_isr,
505 diva_os_soft_isr_callback_t callback,
506 void *callback_context)
507{
508 diva_os_thread_dpc_t *pdpc;
509
510 pdpc = (diva_os_thread_dpc_t *) diva_os_malloc(0, sizeof(*pdpc));
511 if (!(psoft_isr->object = pdpc)) {
512 return (-1);
513 }
514 memset(pdpc, 0x00, sizeof(*pdpc));
515 psoft_isr->callback = callback;
516 psoft_isr->callback_context = callback_context;
517 pdpc->psoft_isr = psoft_isr;
518 tasklet_init(&pdpc->divas_task, diva_os_dpc_proc, (unsigned long)pdpc);
519
520 return (0);
521}
522
523int diva_os_schedule_soft_isr(diva_os_soft_isr_t *psoft_isr)
524{
525 if (psoft_isr && psoft_isr->object) {
526 diva_os_thread_dpc_t *pdpc =
527 (diva_os_thread_dpc_t *) psoft_isr->object;
528
529 tasklet_schedule(&pdpc->divas_task);
530 }
531
532 return (1);
533}
534
535int diva_os_cancel_soft_isr(diva_os_soft_isr_t *psoft_isr)
536{
537 return (0);
538}
539
540void diva_os_remove_soft_isr(diva_os_soft_isr_t *psoft_isr)
541{
542 if (psoft_isr && psoft_isr->object) {
543 diva_os_thread_dpc_t *pdpc =
544 (diva_os_thread_dpc_t *) psoft_isr->object;
545 void *mem;
546
547 tasklet_kill(&pdpc->divas_task);
548 mem = psoft_isr->object;
549 psoft_isr->object = NULL;
550 diva_os_free(0, mem);
551 }
552}
553
554/*
555 * kernel/user space copy functions
556 */
557static int
558xdi_copy_to_user(void *os_handle, void __user *dst, const void *src, int length)
559{
560 if (copy_to_user(dst, src, length)) {
561 return (-EFAULT);
562 }
563 return (length);
564}
565
566static int
567xdi_copy_from_user(void *os_handle, void *dst, const void __user *src, int length)
568{
569 if (copy_from_user(dst, src, length)) {
570 return (-EFAULT);
571 }
572 return (length);
573}
574
575/*
576 * device node operations
577 */
578static int divas_open(struct inode *inode, struct file *file)
579{
580 return (0);
581}
582
583static int divas_release(struct inode *inode, struct file *file)
584{
585 if (file->private_data) {
586 diva_xdi_close_adapter(file->private_data, file);
587 }
588 return (0);
589}
590
591static ssize_t divas_write(struct file *file, const char __user *buf,
592 size_t count, loff_t *ppos)
593{
594 diva_xdi_um_cfg_cmd_t msg;
595 int ret = -EINVAL;
596
597 if (!file->private_data) {
598 file->private_data = diva_xdi_open_adapter(file, buf,
599 count, &msg,
600 xdi_copy_from_user);
601 if (!file->private_data)
602 return (-ENODEV);
603 ret = diva_xdi_write(file->private_data, file,
604 buf, count, &msg, xdi_copy_from_user);
605 } else {
606 ret = diva_xdi_write(file->private_data, file,
607 buf, count, NULL, xdi_copy_from_user);
608 }
609
610 switch (ret) {
611 case -1: /* Message should be removed from rx mailbox first */
612 ret = -EBUSY;
613 break;
614 case -2: /* invalid adapter was specified in this call */
615 ret = -ENOMEM;
616 break;
617 case -3:
618 ret = -ENXIO;
619 break;
620 }
621 DBG_TRC(("write: ret %d", ret));
622 return (ret);
623}
624
625static ssize_t divas_read(struct file *file, char __user *buf,
626 size_t count, loff_t *ppos)
627{
628 diva_xdi_um_cfg_cmd_t msg;
629 int ret = -EINVAL;
630
631 if (!file->private_data) {
632 file->private_data = diva_xdi_open_adapter(file, buf,
633 count, &msg,
634 xdi_copy_from_user);
635 }
636 if (!file->private_data) {
637 return (-ENODEV);
638 }
639
640 ret = diva_xdi_read(file->private_data, file,
641 buf, count, xdi_copy_to_user);
642 switch (ret) {
643 case -1: /* RX mailbox is empty */
644 ret = -EAGAIN;
645 break;
646 case -2: /* no memory, mailbox was cleared, last command is failed */
647 ret = -ENOMEM;
648 break;
649 case -3: /* can't copy to user, retry */
650 ret = -EFAULT;
651 break;
652 }
653 DBG_TRC(("read: ret %d", ret));
654 return (ret);
655}
656
657static __poll_t divas_poll(struct file *file, poll_table *wait)
658{
659 if (!file->private_data) {
660 return (EPOLLERR);
661 }
662 return (EPOLLIN | EPOLLRDNORM);
663}
664
665static const struct file_operations divas_fops = {
666 .owner = THIS_MODULE,
667 .llseek = no_llseek,
668 .read = divas_read,
669 .write = divas_write,
670 .poll = divas_poll,
671 .open = divas_open,
672 .release = divas_release
673};
674
675static void divas_unregister_chrdev(void)
676{
677 unregister_chrdev(major, DEVNAME);
678}
679
680static int __init divas_register_chrdev(void)
681{
682 if ((major = register_chrdev(0, DEVNAME, &divas_fops)) < 0)
683 {
684 printk(KERN_ERR "%s: failed to create /dev entry.\n",
685 DRIVERLNAME);
686 return (0);
687 }
688
689 return (1);
690}
691
692/* --------------------------------------------------------------------------
693 PCI driver section
694 -------------------------------------------------------------------------- */
695static int divas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
696{
697 void *pdiva = NULL;
698 u8 pci_latency;
699 u8 new_latency = 32;
700
701 DBG_TRC(("%s bus: %08x fn: %08x insertion.\n",
702 CardProperties[ent->driver_data].Name,
703 pdev->bus->number, pdev->devfn))
704 printk(KERN_INFO "%s: %s bus: %08x fn: %08x insertion.\n",
705 DRIVERLNAME, CardProperties[ent->driver_data].Name,
706 pdev->bus->number, pdev->devfn);
707
708 if (pci_enable_device(pdev)) {
709 DBG_TRC(("%s: %s bus: %08x fn: %08x device init failed.\n",
710 DRIVERLNAME,
711 CardProperties[ent->driver_data].Name,
712 pdev->bus->number,
713 pdev->devfn))
714 printk(KERN_ERR
715 "%s: %s bus: %08x fn: %08x device init failed.\n",
716 DRIVERLNAME,
717 CardProperties[ent->driver_data].
718 Name, pdev->bus->number,
719 pdev->devfn);
720 return (-EIO);
721 }
722
723 pci_set_master(pdev);
724
725 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
726 if (!pci_latency) {
727 DBG_TRC(("%s: bus: %08x fn: %08x fix latency.\n",
728 DRIVERLNAME, pdev->bus->number, pdev->devfn))
729 printk(KERN_INFO
730 "%s: bus: %08x fn: %08x fix latency.\n",
731 DRIVERLNAME, pdev->bus->number, pdev->devfn);
732 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
733 }
734
735 if (!(pdiva = diva_driver_add_card(pdev, ent->driver_data))) {
736 DBG_TRC(("%s: %s bus: %08x fn: %08x card init failed.\n",
737 DRIVERLNAME,
738 CardProperties[ent->driver_data].Name,
739 pdev->bus->number,
740 pdev->devfn))
741 printk(KERN_ERR
742 "%s: %s bus: %08x fn: %08x card init failed.\n",
743 DRIVERLNAME,
744 CardProperties[ent->driver_data].
745 Name, pdev->bus->number,
746 pdev->devfn);
747 return (-EIO);
748 }
749
750 pci_set_drvdata(pdev, pdiva);
751
752 return (0);
753}
754
755static void divas_remove_one(struct pci_dev *pdev)
756{
757 void *pdiva = pci_get_drvdata(pdev);
758
759 DBG_TRC(("bus: %08x fn: %08x removal.\n",
760 pdev->bus->number, pdev->devfn))
761 printk(KERN_INFO "%s: bus: %08x fn: %08x removal.\n",
762 DRIVERLNAME, pdev->bus->number, pdev->devfn);
763
764 if (pdiva) {
765 diva_driver_remove_card(pdiva);
766 }
767
768}
769
770/* --------------------------------------------------------------------------
771 Driver Load / Startup
772 -------------------------------------------------------------------------- */
773static int __init divas_init(void)
774{
775 char tmprev[50];
776 int ret = 0;
777
778 printk(KERN_INFO "%s\n", DRIVERNAME);
779 printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_DIVAS);
780 strcpy(tmprev, main_revision);
781 printk("%s Build: %s(%s)\n", getrev(tmprev),
782 diva_xdi_common_code_build, DIVA_BUILD);
783 printk(KERN_INFO "%s: support for: ", DRIVERLNAME);
784#ifdef CONFIG_ISDN_DIVAS_BRIPCI
785 printk("BRI/PCI ");
786#endif
787#ifdef CONFIG_ISDN_DIVAS_PRIPCI
788 printk("PRI/PCI ");
789#endif
790 printk("adapters\n");
791
792 if (!divasfunc_init(dbgmask)) {
793 printk(KERN_ERR "%s: failed to connect to DIDD.\n",
794 DRIVERLNAME);
795 ret = -EIO;
796 goto out;
797 }
798
799 if (!divas_register_chrdev()) {
800#ifdef MODULE
801 divasfunc_exit();
802#endif
803 ret = -EIO;
804 goto out;
805 }
806
807 if (!create_divas_proc()) {
808#ifdef MODULE
809 divas_unregister_chrdev();
810 divasfunc_exit();
811#endif
812 printk(KERN_ERR "%s: failed to create proc entry.\n",
813 DRIVERLNAME);
814 ret = -EIO;
815 goto out;
816 }
817
818 if ((ret = pci_register_driver(&diva_pci_driver))) {
819#ifdef MODULE
820 remove_divas_proc();
821 divas_unregister_chrdev();
822 divasfunc_exit();
823#endif
824 printk(KERN_ERR "%s: failed to init pci driver.\n",
825 DRIVERLNAME);
826 goto out;
827 }
828 printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
829
830out:
831 return (ret);
832}
833
834/* --------------------------------------------------------------------------
835 Driver Unload
836 -------------------------------------------------------------------------- */
837static void __exit divas_exit(void)
838{
839 pci_unregister_driver(&diva_pci_driver);
840 remove_divas_proc();
841 divas_unregister_chrdev();
842 divasfunc_exit();
843
844 printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
845}
846
847module_init(divas_init);
848module_exit(divas_exit);
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
deleted file mode 100644
index f52f4622b10b..000000000000
--- a/drivers/isdn/hardware/eicon/divasproc.c
+++ /dev/null
@@ -1,412 +0,0 @@
1/* $Id: divasproc.c,v 1.19.4.3 2005/01/31 12:22:20 armin Exp $
2 *
3 * Low level driver for Eicon DIVA Server ISDN cards.
4 * /proc functions
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/poll.h>
16#include <linux/proc_fs.h>
17#include <linux/seq_file.h>
18#include <linux/list.h>
19#include <linux/uaccess.h>
20
21#include "platform.h"
22#include "debuglib.h"
23#undef ID_MASK
24#undef N_DATA
25#include "pc.h"
26#include "di_defs.h"
27#include "divasync.h"
28#include "di.h"
29#include "io.h"
30#include "xdi_msg.h"
31#include "xdi_adapter.h"
32#include "diva.h"
33#include "diva_pci.h"
34
35
36extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
37extern void divas_get_version(char *);
38extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf);
39
40/*********************************************************
41 ** Functions for /proc interface / File operations
42 *********************************************************/
43
44static char *divas_proc_name = "divas";
45static char *adapter_dir_name = "adapter";
46static char *info_proc_name = "info";
47static char *grp_opt_proc_name = "group_optimization";
48static char *d_l1_down_proc_name = "dynamic_l1_down";
49
50/*
51** "divas" entry
52*/
53
54extern struct proc_dir_entry *proc_net_eicon;
55static struct proc_dir_entry *divas_proc_entry = NULL;
56
57static ssize_t
58divas_read(struct file *file, char __user *buf, size_t count, loff_t *off)
59{
60 int len = 0;
61 int cadapter;
62 char tmpbuf[80];
63 char tmpser[16];
64
65 if (*off)
66 return 0;
67
68 divas_get_version(tmpbuf);
69 if (copy_to_user(buf + len, &tmpbuf, strlen(tmpbuf)))
70 return -EFAULT;
71 len += strlen(tmpbuf);
72
73 for (cadapter = 0; cadapter < MAX_ADAPTER; cadapter++) {
74 if (IoAdapters[cadapter]) {
75 diva_get_vserial_number(IoAdapters[cadapter],
76 tmpser);
77 sprintf(tmpbuf,
78 "%2d: %-30s Serial:%-10s IRQ:%2d\n",
79 cadapter + 1,
80 IoAdapters[cadapter]->Properties.Name,
81 tmpser,
82 IoAdapters[cadapter]->irq_info.irq_nr);
83 if ((strlen(tmpbuf) + len) > count)
84 break;
85 if (copy_to_user
86 (buf + len, &tmpbuf,
87 strlen(tmpbuf))) return -EFAULT;
88 len += strlen(tmpbuf);
89 }
90 }
91
92 *off += len;
93 return (len);
94}
95
96static ssize_t
97divas_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
98{
99 return (-ENODEV);
100}
101
102static __poll_t divas_poll(struct file *file, poll_table *wait)
103{
104 return (EPOLLERR);
105}
106
107static int divas_open(struct inode *inode, struct file *file)
108{
109 return nonseekable_open(inode, file);
110}
111
112static int divas_close(struct inode *inode, struct file *file)
113{
114 return (0);
115}
116
117static const struct file_operations divas_fops = {
118 .owner = THIS_MODULE,
119 .llseek = no_llseek,
120 .read = divas_read,
121 .write = divas_write,
122 .poll = divas_poll,
123 .open = divas_open,
124 .release = divas_close
125};
126
127int create_divas_proc(void)
128{
129 divas_proc_entry = proc_create(divas_proc_name, S_IFREG | S_IRUGO,
130 proc_net_eicon, &divas_fops);
131 if (!divas_proc_entry)
132 return (0);
133
134 return (1);
135}
136
137void remove_divas_proc(void)
138{
139 if (divas_proc_entry) {
140 remove_proc_entry(divas_proc_name, proc_net_eicon);
141 divas_proc_entry = NULL;
142 }
143}
144
145static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer,
146 size_t count, loff_t *pos)
147{
148 diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file));
149 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
150
151 if ((count == 1) || (count == 2)) {
152 char c;
153 if (get_user(c, buffer))
154 return -EFAULT;
155 switch (c) {
156 case '0':
157 IoAdapter->capi_cfg.cfg_1 &=
158 ~DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON;
159 break;
160 case '1':
161 IoAdapter->capi_cfg.cfg_1 |=
162 DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON;
163 break;
164 default:
165 return (-EINVAL);
166 }
167 return (count);
168 }
169 return (-EINVAL);
170}
171
172static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer,
173 size_t count, loff_t *pos)
174{
175 diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file));
176 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
177
178 if ((count == 1) || (count == 2)) {
179 char c;
180 if (get_user(c, buffer))
181 return -EFAULT;
182 switch (c) {
183 case '0':
184 IoAdapter->capi_cfg.cfg_1 &=
185 ~DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON;
186 break;
187 case '1':
188 IoAdapter->capi_cfg.cfg_1 |=
189 DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON;
190 break;
191 default:
192 return (-EINVAL);
193 }
194 return (count);
195 }
196 return (-EINVAL);
197}
198
199static int d_l1_down_proc_show(struct seq_file *m, void *v)
200{
201 diva_os_xdi_adapter_t *a = m->private;
202 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
203
204 seq_printf(m, "%s\n",
205 (IoAdapter->capi_cfg.
206 cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" :
207 "0");
208 return 0;
209}
210
211static int d_l1_down_proc_open(struct inode *inode, struct file *file)
212{
213 return single_open(file, d_l1_down_proc_show, PDE_DATA(inode));
214}
215
216static const struct file_operations d_l1_down_proc_fops = {
217 .owner = THIS_MODULE,
218 .open = d_l1_down_proc_open,
219 .read = seq_read,
220 .llseek = seq_lseek,
221 .release = single_release,
222 .write = d_l1_down_proc_write,
223};
224
225static int grp_opt_proc_show(struct seq_file *m, void *v)
226{
227 diva_os_xdi_adapter_t *a = m->private;
228 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
229
230 seq_printf(m, "%s\n",
231 (IoAdapter->capi_cfg.
232 cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON)
233 ? "1" : "0");
234 return 0;
235}
236
237static int grp_opt_proc_open(struct inode *inode, struct file *file)
238{
239 return single_open(file, grp_opt_proc_show, PDE_DATA(inode));
240}
241
242static const struct file_operations grp_opt_proc_fops = {
243 .owner = THIS_MODULE,
244 .open = grp_opt_proc_open,
245 .read = seq_read,
246 .llseek = seq_lseek,
247 .release = single_release,
248 .write = grp_opt_proc_write,
249};
250
251static ssize_t info_proc_write(struct file *file, const char __user *buffer,
252 size_t count, loff_t *pos)
253{
254 diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file));
255 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
256 char c[4];
257
258 if (count <= 4)
259 return -EINVAL;
260
261 if (copy_from_user(c, buffer, 4))
262 return -EFAULT;
263
264 /* this is for test purposes only */
265 if (!memcmp(c, "trap", 4)) {
266 (*(IoAdapter->os_trap_nfy_Fnc)) (IoAdapter, IoAdapter->ANum);
267 return (count);
268 }
269 return (-EINVAL);
270}
271
272static int info_proc_show(struct seq_file *m, void *v)
273{
274 int i = 0;
275 char *p;
276 char tmpser[16];
277 diva_os_xdi_adapter_t *a = m->private;
278 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
279
280 seq_printf(m, "Name : %s\n", IoAdapter->Properties.Name);
281 seq_printf(m, "DSP state : %08x\n", a->dsp_mask);
282 seq_printf(m, "Channels : %02d\n", IoAdapter->Properties.Channels);
283 seq_printf(m, "E. max/used : %03d/%03d\n",
284 IoAdapter->e_max, IoAdapter->e_count);
285 diva_get_vserial_number(IoAdapter, tmpser);
286 seq_printf(m, "Serial : %s\n", tmpser);
287 seq_printf(m, "IRQ : %d\n", IoAdapter->irq_info.irq_nr);
288 seq_printf(m, "CardIndex : %d\n", a->CardIndex);
289 seq_printf(m, "CardOrdinal : %d\n", a->CardOrdinal);
290 seq_printf(m, "Controller : %d\n", a->controller);
291 seq_printf(m, "Bus-Type : %s\n",
292 (a->Bus ==
293 DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI");
294 seq_printf(m, "Port-Name : %s\n", a->port_name);
295 if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) {
296 seq_printf(m, "PCI-bus : %d\n", a->resources.pci.bus);
297 seq_printf(m, "PCI-func : %d\n", a->resources.pci.func);
298 for (i = 0; i < 8; i++) {
299 if (a->resources.pci.bar[i]) {
300 seq_printf(m,
301 "Mem / I/O %d : 0x%x / mapped : 0x%lx",
302 i, a->resources.pci.bar[i],
303 (unsigned long) a->resources.
304 pci.addr[i]);
305 if (a->resources.pci.length[i]) {
306 seq_printf(m,
307 " / length : %d",
308 a->resources.pci.
309 length[i]);
310 }
311 seq_putc(m, '\n');
312 }
313 }
314 }
315 if ((!a->xdi_adapter.port) &&
316 ((!a->xdi_adapter.ram) ||
317 (!a->xdi_adapter.reset)
318 || (!a->xdi_adapter.cfg))) {
319 if (!IoAdapter->irq_info.irq_nr) {
320 p = "slave";
321 } else {
322 p = "out of service";
323 }
324 } else if (a->xdi_adapter.trapped) {
325 p = "trapped";
326 } else if (a->xdi_adapter.Initialized) {
327 p = "active";
328 } else {
329 p = "ready";
330 }
331 seq_printf(m, "State : %s\n", p);
332
333 return 0;
334}
335
336static int info_proc_open(struct inode *inode, struct file *file)
337{
338 return single_open(file, info_proc_show, PDE_DATA(inode));
339}
340
341static const struct file_operations info_proc_fops = {
342 .owner = THIS_MODULE,
343 .open = info_proc_open,
344 .read = seq_read,
345 .llseek = seq_lseek,
346 .release = single_release,
347 .write = info_proc_write,
348};
349
350/*
351** adapter proc init/de-init
352*/
353
354/* --------------------------------------------------------------------------
355 Create adapter directory and files in proc file system
356 -------------------------------------------------------------------------- */
357int create_adapter_proc(diva_os_xdi_adapter_t *a)
358{
359 struct proc_dir_entry *de, *pe;
360 char tmp[16];
361
362 sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
363 if (!(de = proc_mkdir(tmp, proc_net_eicon)))
364 return (0);
365 a->proc_adapter_dir = (void *) de;
366
367 pe = proc_create_data(info_proc_name, S_IRUGO | S_IWUSR, de,
368 &info_proc_fops, a);
369 if (!pe)
370 return (0);
371 a->proc_info = (void *) pe;
372
373 pe = proc_create_data(grp_opt_proc_name, S_IRUGO | S_IWUSR, de,
374 &grp_opt_proc_fops, a);
375 if (pe)
376 a->proc_grp_opt = (void *) pe;
377 pe = proc_create_data(d_l1_down_proc_name, S_IRUGO | S_IWUSR, de,
378 &d_l1_down_proc_fops, a);
379 if (pe)
380 a->proc_d_l1_down = (void *) pe;
381
382 DBG_TRC(("proc entry %s created", tmp));
383
384 return (1);
385}
386
387/* --------------------------------------------------------------------------
388 Remove adapter directory and files in proc file system
389 -------------------------------------------------------------------------- */
390void remove_adapter_proc(diva_os_xdi_adapter_t *a)
391{
392 char tmp[16];
393
394 if (a->proc_adapter_dir) {
395 if (a->proc_d_l1_down) {
396 remove_proc_entry(d_l1_down_proc_name,
397 (struct proc_dir_entry *) a->proc_adapter_dir);
398 }
399 if (a->proc_grp_opt) {
400 remove_proc_entry(grp_opt_proc_name,
401 (struct proc_dir_entry *) a->proc_adapter_dir);
402 }
403 if (a->proc_info) {
404 remove_proc_entry(info_proc_name,
405 (struct proc_dir_entry *) a->proc_adapter_dir);
406 }
407 sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
408 remove_proc_entry(tmp, proc_net_eicon);
409 DBG_TRC(("proc entry %s%d removed", adapter_dir_name,
410 a->controller));
411 }
412}
diff --git a/drivers/isdn/hardware/eicon/divasync.h b/drivers/isdn/hardware/eicon/divasync.h
deleted file mode 100644
index dd6b53a2c2c8..000000000000
--- a/drivers/isdn/hardware/eicon/divasync.h
+++ /dev/null
@@ -1,489 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_SYNC__H
27#define __DIVA_SYNC__H
28#define IDI_SYNC_REQ_REMOVE 0x00
29#define IDI_SYNC_REQ_GET_NAME 0x01
30#define IDI_SYNC_REQ_GET_SERIAL 0x02
31#define IDI_SYNC_REQ_SET_POSTCALL 0x03
32#define IDI_SYNC_REQ_GET_XLOG 0x04
33#define IDI_SYNC_REQ_GET_FEATURES 0x05
34#define IDI_SYNC_REQ_USB_REGISTER 0x06
35#define IDI_SYNC_REQ_USB_RELEASE 0x07
36#define IDI_SYNC_REQ_USB_ADD_DEVICE 0x08
37#define IDI_SYNC_REQ_USB_START_DEVICE 0x09
38#define IDI_SYNC_REQ_USB_STOP_DEVICE 0x0A
39#define IDI_SYNC_REQ_USB_REMOVE_DEVICE 0x0B
40#define IDI_SYNC_REQ_GET_CARDTYPE 0x0C
41#define IDI_SYNC_REQ_GET_DBG_XLOG 0x0D
42#define DIVA_USB
43#define DIVA_USB_REQ 0xAC
44#define DIVA_USB_TEST 0xAB
45#define DIVA_USB_ADD_ADAPTER 0xAC
46#define DIVA_USB_REMOVE_ADAPTER 0xAD
47#define IDI_SYNC_REQ_SERIAL_HOOK 0x80
48#define IDI_SYNC_REQ_XCHANGE_STATUS 0x81
49#define IDI_SYNC_REQ_USB_HOOK 0x82
50#define IDI_SYNC_REQ_PORTDRV_HOOK 0x83
51#define IDI_SYNC_REQ_SLI 0x84 /* SLI request from 3signal modem drivers */
52#define IDI_SYNC_REQ_RECONFIGURE 0x85
53#define IDI_SYNC_REQ_RESET 0x86
54#define IDI_SYNC_REQ_GET_85X_DEVICE_DATA 0x87
55#define IDI_SYNC_REQ_LOCK_85X 0x88
56#define IDI_SYNC_REQ_DIVA_85X_USB_DATA_EXCHANGE 0x99
57#define IDI_SYNC_REQ_DIPORT_EXCHANGE_REQ 0x98
58#define IDI_SYNC_REQ_GET_85X_EXT_PORT_TYPE 0xA0
59/******************************************************************************/
60#define IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES 0x92
61/*
62 To receive XDI features:
63 1. set 'buffer_length_in_bytes' to length of you buffer
64 2. set 'features' to pointer to your buffer
65 3. issue synchronous request to XDI
66 4. Check that feature 'DIVA_XDI_EXTENDED_FEATURES_VALID' is present
67 after call. This feature does indicate that your request
68 was processed and XDI does support this synchronous request
69 5. if on return bit 31 (0x80000000) in 'buffer_length_in_bytes' is
70 set then provided buffer was too small, and bits 30-0 does
71 contain necessary length of buffer.
72 in this case only features that do find place in the buffer
73 are indicated to caller
74*/
75typedef struct _diva_xdi_get_extended_xdi_features {
76 dword buffer_length_in_bytes;
77 byte *features;
78} diva_xdi_get_extended_xdi_features_t;
79/*
80 features[0]
81*/
82#define DIVA_XDI_EXTENDED_FEATURES_VALID 0x01
83#define DIVA_XDI_EXTENDED_FEATURE_CMA 0x02
84#define DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR 0x04
85#define DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS 0x08
86#define DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC 0x10
87#define DIVA_XDI_EXTENDED_FEATURE_RX_DMA 0x20
88#define DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA 0x40
89#define DIVA_XDI_EXTENDED_FEATURE_WIDE_ID 0x80
90#define DIVA_XDI_EXTENDED_FEATURES_MAX_SZ 1
91/******************************************************************************/
92#define IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR 0x93
93typedef struct _diva_xdi_get_adapter_sdram_bar {
94 dword bar;
95} diva_xdi_get_adapter_sdram_bar_t;
96/******************************************************************************/
97#define IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS 0x94
98/*
99 CAPI Parameters will be written in the caller's buffer
100*/
101typedef struct _diva_xdi_get_capi_parameters {
102 dword structure_length;
103 byte flag_dynamic_l1_down;
104 byte group_optimization_enabled;
105} diva_xdi_get_capi_parameters_t;
106/******************************************************************************/
107#define IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER 0x95
108/*
109 Get logical adapter number, as assigned by XDI
110 'controller' is starting with zero 'sub' controller number
111 in case of one adapter that supports multiple interfaces
112 'controller' is zero for Master adapter (and adapter that supports
113 only one interface)
114*/
115typedef struct _diva_xdi_get_logical_adapter_number {
116 dword logical_adapter_number;
117 dword controller;
118 dword total_controllers;
119} diva_xdi_get_logical_adapter_number_s_t;
120/******************************************************************************/
121#define IDI_SYNC_REQ_UP1DM_OPERATION 0x96
122/******************************************************************************/
123#define IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION 0x97
124#define IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC 0x01
125#define IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE 0x02
126typedef struct _diva_xdi_dma_descriptor_operation {
127 int operation;
128 int descriptor_number;
129 void *descriptor_address;
130 dword descriptor_magic;
131} diva_xdi_dma_descriptor_operation_t;
132/******************************************************************************/
133#define IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY 0x01
134#define IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY 0x02
135#define IDI_SYNC_REQ_DIDD_ADD_ADAPTER 0x03
136#define IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER 0x04
137#define IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY 0x05
138#define IDI_SYNC_REQ_DIDD_GET_CFG_LIB_IFC 0x10
139typedef struct _diva_didd_adapter_notify {
140 dword handle; /* Notification handle */
141 void *callback;
142 void *context;
143} diva_didd_adapter_notify_t;
144typedef struct _diva_didd_add_adapter {
145 void *descriptor;
146} diva_didd_add_adapter_t;
147typedef struct _diva_didd_remove_adapter {
148 IDI_CALL p_request;
149} diva_didd_remove_adapter_t;
150typedef struct _diva_didd_read_adapter_array {
151 void *buffer;
152 dword length;
153} diva_didd_read_adapter_array_t;
154typedef struct _diva_didd_get_cfg_lib_ifc {
155 void *ifc;
156} diva_didd_get_cfg_lib_ifc_t;
157/******************************************************************************/
158#define IDI_SYNC_REQ_XDI_GET_STREAM 0x91
159#define DIVA_XDI_SYNCHRONOUS_SERVICE 0x01
160#define DIVA_XDI_DMA_SERVICE 0x02
161#define DIVA_XDI_AUTO_SERVICE 0x03
162#define DIVA_ISTREAM_COMPLETE_NOTIFY 0
163#define DIVA_ISTREAM_COMPLETE_READ 1
164#define DIVA_ISTREAM_COMPLETE_WRITE 2
165typedef struct _diva_xdi_stream_interface {
166 unsigned char Id; /* filled by XDI client */
167 unsigned char provided_service; /* filled by XDI */
168 unsigned char requested_service; /* filled by XDI Client */
169 void *xdi_context; /* filled by XDI */
170 void *client_context; /* filled by XDI client */
171 int (*write)(void *context,
172 int Id,
173 void *data,
174 int length,
175 int final,
176 byte usr1,
177 byte usr2);
178 int (*read)(void *context,
179 int Id,
180 void *data,
181 int max_length,
182 int *final,
183 byte *usr1,
184 byte *usr2);
185 int (*complete)(void *client_context,
186 int Id,
187 int what,
188 void *data,
189 int length,
190 int *final);
191} diva_xdi_stream_interface_t;
192/******************************************************************************/
193/*
194 * IDI_SYNC_REQ_SERIAL_HOOK - special interface for the DIVA Mobile card
195 */
196typedef struct
197{ unsigned char LineState; /* Modem line state (STATUS_R) */
198#define SERIAL_GSM_CELL 0x01 /* GSM or CELL cable attached */
199 unsigned char CardState; /* PCMCIA card state (0 = down) */
200 unsigned char IsdnState; /* ISDN layer 1 state (0 = down)*/
201 unsigned char HookState; /* current logical hook state */
202#define SERIAL_ON_HOOK 0x02 /* set in DIVA CTRL_R register */
203} SERIAL_STATE;
204typedef int (*SERIAL_INT_CB)(void *Context);
205typedef int (*SERIAL_DPC_CB)(void *Context);
206typedef unsigned char (*SERIAL_I_SYNC)(void *Context);
207typedef struct
208{ /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
209 unsigned char Req; /* request (must be always 0) */
210 unsigned char Rc; /* return code (is the request) */
211 unsigned char Function; /* private function code */
212#define SERIAL_HOOK_ATTACH 0x81
213#define SERIAL_HOOK_STATUS 0x82
214#define SERIAL_HOOK_I_SYNC 0x83
215#define SERIAL_HOOK_NOECHO 0x84
216#define SERIAL_HOOK_RING 0x85
217#define SERIAL_HOOK_DETACH 0x8f
218 unsigned char Flags; /* function refinements */
219 /* parameters passed by the ATTACH request */
220 SERIAL_INT_CB InterruptHandler; /* called on each interrupt */
221 SERIAL_DPC_CB DeferredHandler; /* called on hook state changes */
222 void *HandlerContext; /* context for both handlers */
223 /* return values for both the ATTACH and the STATUS request */
224 unsigned long IoBase; /* IO port assigned to UART */
225 SERIAL_STATE State;
226 /* parameters and return values for the I_SYNC function */
227 SERIAL_I_SYNC SyncFunction; /* to be called synchronized */
228 void *SyncContext; /* context for this function */
229 unsigned char SyncResult; /* return value of function */
230} SERIAL_HOOK;
231/*
232 * IDI_SYNC_REQ_XCHANGE_STATUS - exchange the status between IDI and WMP
233 * IDI_SYNC_REQ_RECONFIGURE - reconfiguration of IDI from WMP
234 */
235typedef struct
236{ /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
237 unsigned char Req; /* request (must be always 0) */
238 unsigned char Rc; /* return code (is the request) */
239#define DRIVER_STATUS_BOOT 0xA1
240#define DRIVER_STATUS_INIT_DEV 0xA2
241#define DRIVER_STATUS_RUNNING 0xA3
242#define DRIVER_STATUS_SHUTDOWN 0xAF
243#define DRIVER_STATUS_TRAPPED 0xAE
244 unsigned char wmpStatus; /* exported by WMP */
245 unsigned char idiStatus; /* exported by IDI */
246 unsigned long wizProto; /* from WMP registry to IDI */
247 /* the cardtype value is defined by cardtype.h */
248 unsigned long cardType; /* from IDI registry to WMP */
249 unsigned long nt2; /* from IDI registry to WMP */
250 unsigned long permanent; /* from IDI registry to WMP */
251 unsigned long stableL2; /* from IDI registry to WMP */
252 unsigned long tei; /* from IDI registry to WMP */
253#define CRC4_MASK 0x00000003
254#define L1_TRISTATE_MASK 0x00000004
255#define WATCHDOG_MASK 0x00000008
256#define NO_ORDER_CHECK_MASK 0x00000010
257#define LOW_CHANNEL_MASK 0x00000020
258#define NO_HSCX30_MASK 0x00000040
259#define SET_BOARD 0x00001000
260#define SET_CRC4 0x00030000
261#define SET_L1_TRISTATE 0x00040000
262#define SET_WATCHDOG 0x00080000
263#define SET_NO_ORDER_CHECK 0x00100000
264#define SET_LOW_CHANNEL 0x00200000
265#define SET_NO_HSCX30 0x00400000
266#define SET_MODE 0x00800000
267#define SET_PROTO 0x02000000
268#define SET_CARDTYPE 0x04000000
269#define SET_NT2 0x08000000
270#define SET_PERMANENT 0x10000000
271#define SET_STABLEL2 0x20000000
272#define SET_TEI 0x40000000
273#define SET_NUMBERLEN 0x80000000
274 unsigned long Flag; /* |31-Type-16|15-Mask-0| */
275 unsigned long NumberLen; /* reconfiguration: union is empty */
276 union {
277 struct { /* possible reconfiguration, but ... ; SET_BOARD */
278 unsigned long SerialNumber;
279 char *pCardname; /* di_defs.h: BOARD_NAME_LENGTH */
280 } board;
281 struct { /* reset: need resources */
282 void *pRawResources;
283 void *pXlatResources;
284 } res;
285 struct { /* reconfiguration: wizProto == PROTTYPE_RBSCAS */
286#define GLARE_RESOLVE_MASK 0x00000001
287#define DID_MASK 0x00000002
288#define BEARER_CAP_MASK 0x0000000c
289#define SET_GLARE_RESOLVE 0x00010000
290#define SET_DID 0x00020000
291#define SET_BEARER_CAP 0x000c0000
292 unsigned long Flag; /* |31-Type-16|15-VALUE-0| */
293 unsigned short DigitTimeout;
294 unsigned short AnswerDelay;
295 } rbs;
296 struct { /* reconfiguration: wizProto == PROTTYPE_QSIG */
297#define CALL_REF_LENGTH1_MASK 0x00000001
298#define BRI_CHANNEL_ID_MASK 0x00000002
299#define SET_CALL_REF_LENGTH 0x00010000
300#define SET_BRI_CHANNEL_ID 0x00020000
301 unsigned long Flag; /* |31-Type-16|15-VALUE-0| */
302 } qsig;
303 struct { /* reconfiguration: NumberLen != 0 */
304#define SET_SPID1 0x00010000
305#define SET_NUMBER1 0x00020000
306#define SET_SUBADDRESS1 0x00040000
307#define SET_SPID2 0x00100000
308#define SET_NUMBER2 0x00200000
309#define SET_SUBADDRESS2 0x00400000
310#define MASK_SET 0xffff0000
311 unsigned long Flag; /* |31-Type-16|15-Channel-0| */
312 unsigned char *pBuffer; /* number value */
313 } isdnNo;
314 }
315 parms
316 ;
317} isdnProps;
318/*
319 * IDI_SYNC_REQ_PORTDRV_HOOK - signal plug/unplug (Award Cardware only)
320 */
321typedef void (*PORTDRV_HOOK_CB)(void *Context, int Plug);
322typedef struct
323{ /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
324 unsigned char Req; /* request (must be always 0) */
325 unsigned char Rc; /* return code (is the request) */
326 unsigned char Function; /* private function code */
327 unsigned char Flags; /* function refinements */
328 PORTDRV_HOOK_CB Callback; /* to be called on plug/unplug */
329 void *Context; /* context for callback */
330 unsigned long Info; /* more info if needed */
331} PORTDRV_HOOK;
332/* Codes for the 'Rc' element in structure below. */
333#define SLI_INSTALL (0xA1)
334#define SLI_UNINSTALL (0xA2)
335typedef int (*SLIENTRYPOINT)(void *p3SignalAPI, void *pContext);
336typedef struct
337{ /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
338 unsigned char Req; /* request (must be always 0) */
339 unsigned char Rc; /* return code (is the request) */
340 unsigned char Function; /* private function code */
341 unsigned char Flags; /* function refinements */
342 SLIENTRYPOINT Callback; /* to be called on plug/unplug */
343 void *Context; /* context for callback */
344 unsigned long Info; /* more info if needed */
345} SLIENTRYPOINT_REQ;
346/******************************************************************************/
347/*
348 * Definitions for DIVA USB
349 */
350typedef int (*USB_SEND_REQ)(unsigned char PipeIndex, unsigned char Type, void *Data, int sizeData);
351typedef int (*USB_START_DEV)(void *Adapter, void *Ipac);
352/* called from WDM */
353typedef void (*USB_RECV_NOTIFY)(void *Ipac, void *msg);
354typedef void (*USB_XMIT_NOTIFY)(void *Ipac, unsigned char PipeIndex);
355/******************************************************************************/
356/*
357 * Parameter description for synchronous requests.
358 *
359 * Sorry, must repeat some parts of di_defs.h here because
360 * they are not defined for all operating environments
361 */
362typedef union
363{ ENTITY Entity;
364 struct
365 { /* 'Req' and 'Rc' are at the same place as in the ENTITY struct */
366 unsigned char Req; /* request (must be always 0) */
367 unsigned char Rc; /* return code (is the request) */
368 } Request;
369 struct
370 { unsigned char Req; /* request (must be always 0) */
371 unsigned char Rc; /* return code (0x01) */
372 unsigned char name[BOARD_NAME_LENGTH];
373 } GetName;
374 struct
375 { unsigned char Req; /* request (must be always 0) */
376 unsigned char Rc; /* return code (0x02) */
377 unsigned long serial; /* serial number */
378 } GetSerial;
379 struct
380 { unsigned char Req; /* request (must be always 0) */
381 unsigned char Rc; /* return code (0x02) */
382 unsigned long lineIdx;/* line, 0 if card has only one */
383 } GetLineIdx;
384 struct
385 { unsigned char Req; /* request (must be always 0) */
386 unsigned char Rc; /* return code (0x02) */
387 unsigned long cardtype;/* card type */
388 } GetCardType;
389 struct
390 { unsigned short command;/* command = 0x0300 */
391 unsigned short dummy; /* not used */
392 IDI_CALL callback;/* routine to call back */
393 ENTITY *contxt; /* ptr to entity to use */
394 } PostCall;
395 struct
396 { unsigned char Req; /* request (must be always 0) */
397 unsigned char Rc; /* return code (0x04) */
398 unsigned char pcm[1]; /* buffer (a pc_maint struct) */
399 } GetXlog;
400 struct
401 { unsigned char Req; /* request (must be always 0) */
402 unsigned char Rc; /* return code (0x05) */
403 unsigned short features;/* feature defines see below */
404 } GetFeatures;
405 SERIAL_HOOK SerialHook;
406/* Added for DIVA USB */
407 struct
408 { unsigned char Req;
409 unsigned char Rc;
410 USB_SEND_REQ UsbSendRequest; /* function in Diva Usb WDM driver in usb_os.c, */
411 /* called from usb_drv.c to send a message to our device */
412 /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0); */
413 USB_RECV_NOTIFY usb_recv; /* called from usb_os.c to pass a received message and ptr to IPAC */
414 /* on to usb_drv.c by a call to usb_recv(). */
415 USB_XMIT_NOTIFY usb_xmit; /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */
416 /* to usb_drv.c by a call to usb_xmit(). */
417 USB_START_DEV UsbStartDevice; /* Start the USB Device, in usb_os.c */
418 IDI_CALL callback; /* routine to call back */
419 ENTITY *contxt; /* ptr to entity to use */
420 void **ipac_ptr; /* pointer to struct IPAC in VxD */
421 } Usb_Msg_old;
422/* message used by WDM and VXD to pass pointers of function and IPAC* */
423 struct
424 { unsigned char Req;
425 unsigned char Rc;
426 USB_SEND_REQ pUsbSendRequest;/* function in Diva Usb WDM driver in usb_os.c, */
427 /* called from usb_drv.c to send a message to our device */
428 /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0); */
429 USB_RECV_NOTIFY p_usb_recv; /* called from usb_os.c to pass a received message and ptr to IPAC */
430 /* on to usb_drv.c by a call to usb_recv(). */
431 USB_XMIT_NOTIFY p_usb_xmit; /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */
432 /* to usb_drv.c by a call to usb_xmit().*/
433 void *ipac_ptr; /* &Diva.ipac pointer to struct IPAC in VxD */
434 } Usb_Msg;
435 PORTDRV_HOOK PortdrvHook;
436 SLIENTRYPOINT_REQ sliEntryPointReq;
437 struct {
438 unsigned char Req;
439 unsigned char Rc;
440 diva_xdi_stream_interface_t info;
441 } xdi_stream_info;
442 struct {
443 unsigned char Req;
444 unsigned char Rc;
445 diva_xdi_get_extended_xdi_features_t info;
446 } xdi_extended_features;
447 struct {
448 unsigned char Req;
449 unsigned char Rc;
450 diva_xdi_get_adapter_sdram_bar_t info;
451 } xdi_sdram_bar;
452 struct {
453 unsigned char Req;
454 unsigned char Rc;
455 diva_xdi_get_capi_parameters_t info;
456 } xdi_capi_prms;
457 struct {
458 ENTITY e;
459 diva_didd_adapter_notify_t info;
460 } didd_notify;
461 struct {
462 ENTITY e;
463 diva_didd_add_adapter_t info;
464 } didd_add_adapter;
465 struct {
466 ENTITY e;
467 diva_didd_remove_adapter_t info;
468 } didd_remove_adapter;
469 struct {
470 ENTITY e;
471 diva_didd_read_adapter_array_t info;
472 } didd_read_adapter_array;
473 struct {
474 ENTITY e;
475 diva_didd_get_cfg_lib_ifc_t info;
476 } didd_get_cfg_lib_ifc;
477 struct {
478 unsigned char Req;
479 unsigned char Rc;
480 diva_xdi_get_logical_adapter_number_s_t info;
481 } xdi_logical_adapter_number;
482 struct {
483 unsigned char Req;
484 unsigned char Rc;
485 diva_xdi_dma_descriptor_operation_t info;
486 } xdi_dma_descriptor_operation;
487} IDI_SYNC_REQ;
488/******************************************************************************/
489#endif /* __DIVA_SYNC__H */
diff --git a/drivers/isdn/hardware/eicon/dqueue.c b/drivers/isdn/hardware/eicon/dqueue.c
deleted file mode 100644
index 7958a2536a10..000000000000
--- a/drivers/isdn/hardware/eicon/dqueue.c
+++ /dev/null
@@ -1,110 +0,0 @@
1/* $Id: dqueue.c,v 1.5 2003/04/12 21:40:49 schindler Exp $
2 *
3 * Driver for Eicon DIVA Server ISDN cards.
4 * User Mode IDI Interface
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#include "platform.h"
14#include "dqueue.h"
15
16int
17diva_data_q_init(diva_um_idi_data_queue_t *q,
18 int max_length, int max_segments)
19{
20 int i;
21
22 q->max_length = max_length;
23 q->segments = max_segments;
24
25 for (i = 0; i < q->segments; i++) {
26 q->data[i] = NULL;
27 q->length[i] = 0;
28 }
29 q->read = q->write = q->count = q->segment_pending = 0;
30
31 for (i = 0; i < q->segments; i++) {
32 if (!(q->data[i] = diva_os_malloc(0, q->max_length))) {
33 diva_data_q_finit(q);
34 return (-1);
35 }
36 }
37
38 return (0);
39}
40
41int diva_data_q_finit(diva_um_idi_data_queue_t *q)
42{
43 int i;
44
45 for (i = 0; i < q->segments; i++) {
46 if (q->data[i]) {
47 diva_os_free(0, q->data[i]);
48 }
49 q->data[i] = NULL;
50 q->length[i] = 0;
51 }
52 q->read = q->write = q->count = q->segment_pending = 0;
53
54 return (0);
55}
56
57int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q)
58{
59 return (q->max_length);
60}
61
62void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q)
63{
64 if ((!q->segment_pending) && (q->count < q->segments)) {
65 q->segment_pending = 1;
66 return (q->data[q->write]);
67 }
68
69 return NULL;
70}
71
72void
73diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q, int length)
74{
75 if (q->segment_pending) {
76 q->length[q->write] = length;
77 q->count++;
78 q->write++;
79 if (q->write >= q->segments) {
80 q->write = 0;
81 }
82 q->segment_pending = 0;
83 }
84}
85
86const void *diva_data_q_get_segment4read(const diva_um_idi_data_queue_t *
87 q)
88{
89 if (q->count) {
90 return (q->data[q->read]);
91 }
92 return NULL;
93}
94
95int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q)
96{
97 return (q->length[q->read]);
98}
99
100void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q)
101{
102 if (q->count) {
103 q->length[q->read] = 0;
104 q->count--;
105 q->read++;
106 if (q->read >= q->segments) {
107 q->read = 0;
108 }
109 }
110}
diff --git a/drivers/isdn/hardware/eicon/dqueue.h b/drivers/isdn/hardware/eicon/dqueue.h
deleted file mode 100644
index 2da9799686ab..000000000000
--- a/drivers/isdn/hardware/eicon/dqueue.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: dqueue.h,v 1.1.2.2 2001/02/08 12:25:43 armin Exp $ */
3
4#ifndef _DIVA_USER_MODE_IDI_DATA_QUEUE_H__
5#define _DIVA_USER_MODE_IDI_DATA_QUEUE_H__
6
7#define DIVA_UM_IDI_MAX_MSGS 64
8
9typedef struct _diva_um_idi_data_queue {
10 int segments;
11 int max_length;
12 int read;
13 int write;
14 int count;
15 int segment_pending;
16 void *data[DIVA_UM_IDI_MAX_MSGS];
17 int length[DIVA_UM_IDI_MAX_MSGS];
18} diva_um_idi_data_queue_t;
19
20int diva_data_q_init(diva_um_idi_data_queue_t *q,
21 int max_length, int max_segments);
22int diva_data_q_finit(diva_um_idi_data_queue_t *q);
23int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q);
24void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q);
25void diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q,
26 int length);
27const void *diva_data_q_get_segment4read(const diva_um_idi_data_queue_t *
28 q);
29int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q);
30void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q);
31
32#endif
diff --git a/drivers/isdn/hardware/eicon/dsp_defs.h b/drivers/isdn/hardware/eicon/dsp_defs.h
deleted file mode 100644
index 94828c87e2a4..000000000000
--- a/drivers/isdn/hardware/eicon/dsp_defs.h
+++ /dev/null
@@ -1,301 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef DSP_DEFS_H_
27#define DSP_DEFS_H_
28#include "dspdids.h"
29/*---------------------------------------------------------------------------*/
30#define dsp_download_reserve_space(fp, length)
31/*****************************************************************************/
32/*
33 * OS file access abstraction layer
34 *
35 * I/O functions returns -1 on error, 0 on EOF
36 */
37struct _OsFileHandle_;
38typedef long (*OsFileIo)(struct _OsFileHandle_ *handle,
39 void *buffer,
40 long size);
41typedef long (*OsFileSeek)(struct _OsFileHandle_ *handle,
42 long position,
43 int mode);
44typedef long (*OsCardLoad)(struct _OsFileHandle_ *handle,
45 long length,
46 void **addr);
47typedef struct _OsFileHandle_
48{ void *sysFileDesc;
49 unsigned long sysFileSize;
50 OsFileIo sysFileRead;
51 OsFileSeek sysFileSeek;
52 void *sysLoadDesc;
53 OsCardLoad sysCardLoad;
54} OsFileHandle;
55extern OsFileHandle *OsOpenFile(char *path_name);
56extern void OsCloseFile(OsFileHandle *fp);
57/*****************************************************************************/
58#define DSP_TELINDUS_FILE "dspdload.bin"
59/* special DSP file for BRI cards for Qsig and CornetN because of missing memory */
60#define DSP_QSIG_TELINDUS_FILE "dspdqsig.bin"
61#define DSP_MDM_TELINDUS_FILE "dspdvmdm.bin"
62#define DSP_FAX_TELINDUS_FILE "dspdvfax.bin"
63#define DSP_DIRECTORY_ENTRIES 64
64#define DSP_MEMORY_TYPE_EXTERNAL_DM 0
65#define DSP_MEMORY_TYPE_EXTERNAL_PM 1
66#define DSP_MEMORY_TYPE_INTERNAL_DM 2
67#define DSP_MEMORY_TYPE_INTERNAL_PM 3
68#define DSP_DOWNLOAD_FLAG_BOOTABLE 0x0001
69#define DSP_DOWNLOAD_FLAG_2181 0x0002
70#define DSP_DOWNLOAD_FLAG_TIMECRITICAL 0x0004
71#define DSP_DOWNLOAD_FLAG_COMPAND 0x0008
72#define DSP_MEMORY_BLOCK_COUNT 16
73#define DSP_SEGMENT_PM_FLAG 0x0001
74#define DSP_SEGMENT_SHARED_FLAG 0x0002
75#define DSP_SEGMENT_EXTERNAL_DM DSP_MEMORY_TYPE_EXTERNAL_DM
76#define DSP_SEGMENT_EXTERNAL_PM DSP_MEMORY_TYPE_EXTERNAL_PM
77#define DSP_SEGMENT_INTERNAL_DM DSP_MEMORY_TYPE_INTERNAL_DM
78#define DSP_SEGMENT_INTERNAL_PM DSP_MEMORY_TYPE_INTERNAL_PM
79#define DSP_SEGMENT_FIRST_RELOCATABLE 4
80#define DSP_DATA_BLOCK_PM_FLAG 0x0001
81#define DSP_DATA_BLOCK_DWORD_FLAG 0x0002
82#define DSP_DATA_BLOCK_RESOLVE_FLAG 0x0004
83#define DSP_RELOC_NONE 0x00
84#define DSP_RELOC_SEGMENT_MASK 0x3f
85#define DSP_RELOC_TYPE_MASK 0xc0
86#define DSP_RELOC_TYPE_0 0x00 /* relocation of address in DM word / high part of PM word */
87#define DSP_RELOC_TYPE_1 0x40 /* relocation of address in low part of PM data word */
88#define DSP_RELOC_TYPE_2 0x80 /* relocation of address in standard command */
89#define DSP_RELOC_TYPE_3 0xc0 /* relocation of address in call/jump on flag in */
90#define DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE 48
91#define DSP_COMBIFILE_FORMAT_VERSION_BCD 0x0100
92#define DSP_FILE_FORMAT_IDENTIFICATION_SIZE 48
93#define DSP_FILE_FORMAT_VERSION_BCD 0x0100
94typedef struct tag_dsp_combifile_header
95{
96 char format_identification[DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE];
97 word format_version_bcd;
98 word header_size;
99 word combifile_description_size;
100 word directory_entries;
101 word directory_size;
102 word download_count;
103 word usage_mask_size;
104} t_dsp_combifile_header;
105typedef struct tag_dsp_combifile_directory_entry
106{
107 word card_type_number;
108 word file_set_number;
109} t_dsp_combifile_directory_entry;
110typedef struct tag_dsp_file_header
111{
112 char format_identification[DSP_FILE_FORMAT_IDENTIFICATION_SIZE];
113 word format_version_bcd;
114 word download_id;
115 word download_flags;
116 word required_processing_power;
117 word interface_channel_count;
118 word header_size;
119 word download_description_size;
120 word memory_block_table_size;
121 word memory_block_count;
122 word segment_table_size;
123 word segment_count;
124 word symbol_table_size;
125 word symbol_count;
126 word total_data_size_dm;
127 word data_block_count_dm;
128 word total_data_size_pm;
129 word data_block_count_pm;
130} t_dsp_file_header;
131typedef struct tag_dsp_memory_block_desc
132{
133 word alias_memory_block;
134 word memory_type;
135 word address;
136 word size; /* DSP words */
137} t_dsp_memory_block_desc;
138typedef struct tag_dsp_segment_desc
139{
140 word memory_block;
141 word attributes;
142 word base;
143 word size;
144 word alignment; /* ==0 -> no other legal start address than base */
145} t_dsp_segment_desc;
146typedef struct tag_dsp_symbol_desc
147{
148 word symbol_id;
149 word segment;
150 word offset;
151 word size; /* DSP words */
152} t_dsp_symbol_desc;
153typedef struct tag_dsp_data_block_header
154{
155 word attributes;
156 word segment;
157 word offset;
158 word size; /* DSP words */
159} t_dsp_data_block_header;
160typedef struct tag_dsp_download_desc
161{
162 word download_id;
163 word download_flags;
164 word required_processing_power;
165 word interface_channel_count;
166 word excess_header_size;
167 word memory_block_count;
168 word segment_count;
169 word symbol_count;
170 word data_block_count_dm;
171 word data_block_count_pm;
172 byte *p_excess_header_data;
173 char *p_download_description;
174 t_dsp_memory_block_desc *p_memory_block_table;
175 t_dsp_segment_desc *p_segment_table;
176 t_dsp_symbol_desc *p_symbol_table;
177 word *p_data_blocks_dm;
178 word *p_data_blocks_pm;
179} t_dsp_desc;
180typedef struct tag_dsp_portable_download_desc /* be sure to keep native alignment for MAESTRA's */
181{
182 word download_id;
183 word download_flags;
184 word required_processing_power;
185 word interface_channel_count;
186 word excess_header_size;
187 word memory_block_count;
188 word segment_count;
189 word symbol_count;
190 word data_block_count_dm;
191 word data_block_count_pm;
192 dword p_excess_header_data;
193 dword p_download_description;
194 dword p_memory_block_table;
195 dword p_segment_table;
196 dword p_symbol_table;
197 dword p_data_blocks_dm;
198 dword p_data_blocks_pm;
199} t_dsp_portable_desc;
200#define DSP_DOWNLOAD_INDEX_KERNEL 0
201#define DSP30TX_DOWNLOAD_INDEX_KERNEL 1
202#define DSP30RX_DOWNLOAD_INDEX_KERNEL 2
203#define DSP_MAX_DOWNLOAD_COUNT 64
204#define DSP_DOWNLOAD_MAX_SEGMENTS 16
205#define DSP_UDATA_REQUEST_RECONFIGURE 0
206/*
207 parameters:
208 <word> reconfigure delay (in 8kHz samples)
209 <word> reconfigure code
210 <byte> reconfigure hdlc preamble flags
211*/
212#define DSP_RECONFIGURE_TX_FLAG 0x8000
213#define DSP_RECONFIGURE_SHORT_TRAIN_FLAG 0x4000
214#define DSP_RECONFIGURE_ECHO_PROTECT_FLAG 0x2000
215#define DSP_RECONFIGURE_HDLC_FLAG 0x1000
216#define DSP_RECONFIGURE_SYNC_FLAG 0x0800
217#define DSP_RECONFIGURE_PROTOCOL_MASK 0x00ff
218#define DSP_RECONFIGURE_IDLE 0
219#define DSP_RECONFIGURE_V25 1
220#define DSP_RECONFIGURE_V21_CH2 2
221#define DSP_RECONFIGURE_V27_2400 3
222#define DSP_RECONFIGURE_V27_4800 4
223#define DSP_RECONFIGURE_V29_7200 5
224#define DSP_RECONFIGURE_V29_9600 6
225#define DSP_RECONFIGURE_V33_12000 7
226#define DSP_RECONFIGURE_V33_14400 8
227#define DSP_RECONFIGURE_V17_7200 9
228#define DSP_RECONFIGURE_V17_9600 10
229#define DSP_RECONFIGURE_V17_12000 11
230#define DSP_RECONFIGURE_V17_14400 12
231/*
232 data indications if transparent framer
233 <byte> data 0
234 <byte> data 1
235 ...
236 data indications if HDLC framer
237 <byte> data 0
238 <byte> data 1
239 ...
240 <byte> CRC 0
241 <byte> CRC 1
242 <byte> preamble flags
243*/
244#define DSP_UDATA_INDICATION_SYNC 0
245/*
246 returns:
247 <word> time of sync (sampled from counter at 8kHz)
248*/
249#define DSP_UDATA_INDICATION_DCD_OFF 1
250/*
251 returns:
252 <word> time of DCD off (sampled from counter at 8kHz)
253*/
254#define DSP_UDATA_INDICATION_DCD_ON 2
255/*
256 returns:
257 <word> time of DCD on (sampled from counter at 8kHz)
258 <byte> connected norm
259 <word> connected options
260 <dword> connected speed (bit/s)
261*/
262#define DSP_UDATA_INDICATION_CTS_OFF 3
263/*
264 returns:
265 <word> time of CTS off (sampled from counter at 8kHz)
266*/
267#define DSP_UDATA_INDICATION_CTS_ON 4
268/*
269 returns:
270 <word> time of CTS on (sampled from counter at 8kHz)
271 <byte> connected norm
272 <word> connected options
273 <dword> connected speed (bit/s)
274*/
275#define DSP_CONNECTED_NORM_UNSPECIFIED 0
276#define DSP_CONNECTED_NORM_V21 1
277#define DSP_CONNECTED_NORM_V23 2
278#define DSP_CONNECTED_NORM_V22 3
279#define DSP_CONNECTED_NORM_V22_BIS 4
280#define DSP_CONNECTED_NORM_V32_BIS 5
281#define DSP_CONNECTED_NORM_V34 6
282#define DSP_CONNECTED_NORM_V8 7
283#define DSP_CONNECTED_NORM_BELL_212A 8
284#define DSP_CONNECTED_NORM_BELL_103 9
285#define DSP_CONNECTED_NORM_V29_LEASED_LINE 10
286#define DSP_CONNECTED_NORM_V33_LEASED_LINE 11
287#define DSP_CONNECTED_NORM_TFAST 12
288#define DSP_CONNECTED_NORM_V21_CH2 13
289#define DSP_CONNECTED_NORM_V27_TER 14
290#define DSP_CONNECTED_NORM_V29 15
291#define DSP_CONNECTED_NORM_V33 16
292#define DSP_CONNECTED_NORM_V17 17
293#define DSP_CONNECTED_OPTION_TRELLIS 0x0001
294/*---------------------------------------------------------------------------*/
295extern char *dsp_read_file(OsFileHandle *fp,
296 word card_type_number,
297 word *p_dsp_download_count,
298 t_dsp_desc *p_dsp_download_table,
299 t_dsp_portable_desc *p_dsp_portable_download_table);
300/*---------------------------------------------------------------------------*/
301#endif /* DSP_DEFS_H_ */
diff --git a/drivers/isdn/hardware/eicon/dsp_tst.h b/drivers/isdn/hardware/eicon/dsp_tst.h
deleted file mode 100644
index 85edd3ea50f7..000000000000
--- a/drivers/isdn/hardware/eicon/dsp_tst.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: dsp_tst.h,v 1.1.2.2 2001/02/08 12:25:43 armin Exp $ */
3
4#ifndef __DIVA_PRI_HOST_TEST_DSPS_H__
5#define __DIVA_PRI_HOST_TEST_DSPS_H__
6
7/*
8 DSP registers on maestra pri
9*/
10#define DSP1_PORT (0x00)
11#define DSP2_PORT (0x8)
12#define DSP3_PORT (0x800)
13#define DSP4_PORT (0x808)
14#define DSP5_PORT (0x810)
15#define DSP6_PORT (0x818)
16#define DSP7_PORT (0x820)
17#define DSP8_PORT (0x828)
18#define DSP9_PORT (0x830)
19#define DSP10_PORT (0x840)
20#define DSP11_PORT (0x848)
21#define DSP12_PORT (0x850)
22#define DSP13_PORT (0x858)
23#define DSP14_PORT (0x860)
24#define DSP15_PORT (0x868)
25#define DSP16_PORT (0x870)
26#define DSP17_PORT (0x1000)
27#define DSP18_PORT (0x1008)
28#define DSP19_PORT (0x1010)
29#define DSP20_PORT (0x1018)
30#define DSP21_PORT (0x1020)
31#define DSP22_PORT (0x1028)
32#define DSP23_PORT (0x1030)
33#define DSP24_PORT (0x1040)
34#define DSP25_PORT (0x1048)
35#define DSP26_PORT (0x1050)
36#define DSP27_PORT (0x1058)
37#define DSP28_PORT (0x1060)
38#define DSP29_PORT (0x1068)
39#define DSP30_PORT (0x1070)
40#define DSP_ADR_OFFS 0x80
41
42/*------------------------------------------------------------------
43 Dsp related definitions
44 ------------------------------------------------------------------ */
45#define DSP_SIGNATURE_PROBE_WORD 0x5a5a
46#define dsp_make_address_ex(pm, address) ((word)((pm) ? (address) : (address) + 0x4000))
47
48#endif
diff --git a/drivers/isdn/hardware/eicon/dspdids.h b/drivers/isdn/hardware/eicon/dspdids.h
deleted file mode 100644
index 957b33cc0022..000000000000
--- a/drivers/isdn/hardware/eicon/dspdids.h
+++ /dev/null
@@ -1,75 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef DSPDIDS_H_
27#define DSPDIDS_H_
28/*---------------------------------------------------------------------------*/
29#define DSP_DID_INVALID 0
30#define DSP_DID_DIVA 1
31#define DSP_DID_DIVA_PRO 2
32#define DSP_DID_DIVA_PRO_20 3
33#define DSP_DID_DIVA_PRO_PCCARD 4
34#define DSP_DID_DIVA_SERVER_BRI_1M 5
35#define DSP_DID_DIVA_SERVER_BRI_2M 6
36#define DSP_DID_DIVA_SERVER_PRI_2M_TX 7
37#define DSP_DID_DIVA_SERVER_PRI_2M_RX 8
38#define DSP_DID_DIVA_SERVER_PRI_30M 9
39#define DSP_DID_TASK_HSCX 100
40#define DSP_DID_TASK_HSCX_PRI_2M_TX 101
41#define DSP_DID_TASK_HSCX_PRI_2M_RX 102
42#define DSP_DID_TASK_V110KRNL 200
43#define DSP_DID_OVERLAY_V1100 201
44#define DSP_DID_OVERLAY_V1101 202
45#define DSP_DID_OVERLAY_V1102 203
46#define DSP_DID_OVERLAY_V1103 204
47#define DSP_DID_OVERLAY_V1104 205
48#define DSP_DID_OVERLAY_V1105 206
49#define DSP_DID_OVERLAY_V1106 207
50#define DSP_DID_OVERLAY_V1107 208
51#define DSP_DID_OVERLAY_V1108 209
52#define DSP_DID_OVERLAY_V1109 210
53#define DSP_DID_TASK_V110_PRI_2M_TX 220
54#define DSP_DID_TASK_V110_PRI_2M_RX 221
55#define DSP_DID_TASK_MODEM 300
56#define DSP_DID_TASK_FAX05 400
57#define DSP_DID_TASK_VOICE 500
58#define DSP_DID_TASK_TIKRNL81 600
59#define DSP_DID_OVERLAY_DIAL 601
60#define DSP_DID_OVERLAY_V22 602
61#define DSP_DID_OVERLAY_V32 603
62#define DSP_DID_OVERLAY_FSK 604
63#define DSP_DID_OVERLAY_FAX 605
64#define DSP_DID_OVERLAY_VXX 606
65#define DSP_DID_OVERLAY_V8 607
66#define DSP_DID_OVERLAY_INFO 608
67#define DSP_DID_OVERLAY_V34 609
68#define DSP_DID_OVERLAY_DFX 610
69#define DSP_DID_PARTIAL_OVERLAY_DIAL 611
70#define DSP_DID_PARTIAL_OVERLAY_FSK 612
71#define DSP_DID_PARTIAL_OVERLAY_FAX 613
72#define DSP_DID_TASK_TIKRNL05 700
73/*---------------------------------------------------------------------------*/
74#endif
75/*---------------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/dsrv4bri.h b/drivers/isdn/hardware/eicon/dsrv4bri.h
deleted file mode 100644
index f353fb6b8933..000000000000
--- a/drivers/isdn/hardware/eicon/dsrv4bri.h
+++ /dev/null
@@ -1,40 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_XDI_DSRV_4_BRI_INC__
27#define __DIVA_XDI_DSRV_4_BRI_INC__
28/*
29 * Some special registers in the PLX 9054
30 */
31#define PLX9054_P2LDBELL 0x60
32#define PLX9054_L2PDBELL 0x64
33#define PLX9054_INTCSR 0x69
34#define PLX9054_INT_ENABLE 0x09
35#define PLX9054_SOFT_RESET 0x4000
36#define PLX9054_RELOAD_EEPROM 0x2000
37#define DIVA_4BRI_REVISION(__x__) (((__x__)->cardType == CARDTYPE_DIVASRV_Q_8M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_B_2M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_B_2F_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI))
38void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter);
39void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter);
40#endif
diff --git a/drivers/isdn/hardware/eicon/dsrv_bri.h b/drivers/isdn/hardware/eicon/dsrv_bri.h
deleted file mode 100644
index 8a67dbc65be4..000000000000
--- a/drivers/isdn/hardware/eicon/dsrv_bri.h
+++ /dev/null
@@ -1,37 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_XDI_DSRV_BRI_INC__
27#define __DIVA_XDI_DSRV_BRI_INC__
28/*
29 Functions exported from os dependent part of
30 BRI card configuration and used in
31 OS independed part
32*/
33/*
34 Prepare OS dependent part of BRI functions
35*/
36void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
37#endif
diff --git a/drivers/isdn/hardware/eicon/dsrv_pri.h b/drivers/isdn/hardware/eicon/dsrv_pri.h
deleted file mode 100644
index fd1a9ff9f195..000000000000
--- a/drivers/isdn/hardware/eicon/dsrv_pri.h
+++ /dev/null
@@ -1,38 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_XDI_DSRV_PRI_INC__
27#define __DIVA_XDI_DSRV_PRI_INC__
28/*
29 Functions exported from os dependent part of
30 PRI card configuration and used in
31 OS independed part
32*/
33/*
34 Prepare OS dependent part of PRI/PRI Rev.2 functions
35*/
36void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter);
37void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
38#endif
diff --git a/drivers/isdn/hardware/eicon/entity.h b/drivers/isdn/hardware/eicon/entity.h
deleted file mode 100644
index f9767d321db9..000000000000
--- a/drivers/isdn/hardware/eicon/entity.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: entity.h,v 1.4 2004/03/21 17:26:01 armin Exp $ */
3
4#ifndef __DIVAS_USER_MODE_IDI_ENTITY__
5#define __DIVAS_USER_MODE_IDI_ENTITY__
6
7#define DIVA_UM_IDI_RC_PENDING 0x00000001
8#define DIVA_UM_IDI_REMOVE_PENDING 0x00000002
9#define DIVA_UM_IDI_TX_FLOW_CONTROL 0x00000004
10#define DIVA_UM_IDI_REMOVED 0x00000008
11#define DIVA_UM_IDI_ASSIGN_PENDING 0x00000010
12
13typedef struct _divas_um_idi_entity {
14 struct list_head link;
15 diva_um_idi_adapter_t *adapter; /* Back to adapter */
16 ENTITY e;
17 void *os_ref;
18 dword status;
19 void *os_context;
20 int rc_count;
21 diva_um_idi_data_queue_t data; /* definad by user 1 ... MAX */
22 diva_um_idi_data_queue_t rc; /* two entries */
23 BUFFERS XData;
24 BUFFERS RData;
25 byte buffer[2048 + 512];
26} divas_um_idi_entity_t;
27
28
29#endif
diff --git a/drivers/isdn/hardware/eicon/helpers.h b/drivers/isdn/hardware/eicon/helpers.h
deleted file mode 100644
index c9156b0acaba..000000000000
--- a/drivers/isdn/hardware/eicon/helpers.h
+++ /dev/null
@@ -1,51 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_XDI_CARD_CONFIG_HELPERS_INC__
27#define __DIVA_XDI_CARD_CONFIG_HELPERS_INC__
28dword diva_get_protocol_file_features(byte *File,
29 int offset,
30 char *IdStringBuffer,
31 dword IdBufferSize);
32void diva_configure_protocol(PISDN_ADAPTER IoAdapter);
33/*
34 Low level file access system abstraction
35*/
36/* -------------------------------------------------------------------------
37 Access to single file
38 Return pointer to the image of the requested file,
39 write image length to 'FileLength'
40 ------------------------------------------------------------------------- */
41void *xdiLoadFile(char *FileName, dword *FileLength, unsigned long MaxLoadSize);
42/* -------------------------------------------------------------------------
43 Dependent on the protocol settings does read return pointer
44 to the image of appropriate protocol file
45 ------------------------------------------------------------------------- */
46void *xdiLoadArchive(PISDN_ADAPTER IoAdapter, dword *FileLength, unsigned long MaxLoadSize);
47/* --------------------------------------------------------------------------
48 Free all system resources accessed by xdiLoadFile and xdiLoadArchive
49 -------------------------------------------------------------------------- */
50void xdiFreeFile(void *handle);
51#endif
diff --git a/drivers/isdn/hardware/eicon/idifunc.c b/drivers/isdn/hardware/eicon/idifunc.c
deleted file mode 100644
index fef6586fe5ac..000000000000
--- a/drivers/isdn/hardware/eicon/idifunc.c
+++ /dev/null
@@ -1,268 +0,0 @@
1/* $Id: idifunc.c,v 1.14.4.4 2004/08/28 20:03:53 armin Exp $
2 *
3 * Driver for Eicon DIVA Server ISDN cards.
4 * User Mode IDI Interface
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#include "platform.h"
14#include "di_defs.h"
15#include "divasync.h"
16#include "um_xdi.h"
17#include "um_idi.h"
18
19#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
20#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
21
22extern char *DRIVERRELEASE_IDI;
23
24extern void DIVA_DIDD_Read(void *, int);
25extern int diva_user_mode_idi_create_adapter(const DESCRIPTOR *, int);
26extern void diva_user_mode_idi_remove_adapter(int);
27
28static dword notify_handle;
29static DESCRIPTOR DAdapter;
30static DESCRIPTOR MAdapter;
31
32static void no_printf(unsigned char *x, ...)
33{
34 /* dummy debug function */
35}
36
37#include "debuglib.c"
38
39/*
40 * stop debug
41 */
42static void stop_dbg(void)
43{
44 DbgDeregister();
45 memset(&MAdapter, 0, sizeof(MAdapter));
46 dprintf = no_printf;
47}
48
49typedef struct _udiva_card {
50 struct list_head list;
51 int Id;
52 DESCRIPTOR d;
53} udiva_card;
54
55static LIST_HEAD(cards);
56static diva_os_spin_lock_t ll_lock;
57
58/*
59 * find card in list
60 */
61static udiva_card *find_card_in_list(DESCRIPTOR *d)
62{
63 udiva_card *card;
64 struct list_head *tmp;
65 diva_os_spin_lock_magic_t old_irql;
66
67 diva_os_enter_spin_lock(&ll_lock, &old_irql, "find card");
68 list_for_each(tmp, &cards) {
69 card = list_entry(tmp, udiva_card, list);
70 if (card->d.request == d->request) {
71 diva_os_leave_spin_lock(&ll_lock, &old_irql,
72 "find card");
73 return (card);
74 }
75 }
76 diva_os_leave_spin_lock(&ll_lock, &old_irql, "find card");
77 return ((udiva_card *) NULL);
78}
79
80/*
81 * new card
82 */
83static void um_new_card(DESCRIPTOR *d)
84{
85 int adapter_nr = 0;
86 udiva_card *card = NULL;
87 IDI_SYNC_REQ sync_req;
88 diva_os_spin_lock_magic_t old_irql;
89
90 if (!(card = diva_os_malloc(0, sizeof(udiva_card)))) {
91 DBG_ERR(("cannot get buffer for card"));
92 return;
93 }
94 memcpy(&card->d, d, sizeof(DESCRIPTOR));
95 sync_req.xdi_logical_adapter_number.Req = 0;
96 sync_req.xdi_logical_adapter_number.Rc =
97 IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;
98 card->d.request((ENTITY *)&sync_req);
99 adapter_nr =
100 sync_req.xdi_logical_adapter_number.info.logical_adapter_number;
101 card->Id = adapter_nr;
102 if (!(diva_user_mode_idi_create_adapter(d, adapter_nr))) {
103 diva_os_enter_spin_lock(&ll_lock, &old_irql, "add card");
104 list_add_tail(&card->list, &cards);
105 diva_os_leave_spin_lock(&ll_lock, &old_irql, "add card");
106 } else {
107 DBG_ERR(("could not create user mode idi card %d",
108 adapter_nr));
109 diva_os_free(0, card);
110 }
111}
112
113/*
114 * remove card
115 */
116static void um_remove_card(DESCRIPTOR *d)
117{
118 diva_os_spin_lock_magic_t old_irql;
119 udiva_card *card = NULL;
120
121 if (!(card = find_card_in_list(d))) {
122 DBG_ERR(("cannot find card to remove"));
123 return;
124 }
125 diva_user_mode_idi_remove_adapter(card->Id);
126 diva_os_enter_spin_lock(&ll_lock, &old_irql, "remove card");
127 list_del(&card->list);
128 diva_os_leave_spin_lock(&ll_lock, &old_irql, "remove card");
129 DBG_LOG(("idi proc entry removed for card %d", card->Id));
130 diva_os_free(0, card);
131}
132
133/*
134 * remove all adapter
135 */
136static void __exit remove_all_idi_proc(void)
137{
138 udiva_card *card;
139 diva_os_spin_lock_magic_t old_irql;
140
141rescan:
142 diva_os_enter_spin_lock(&ll_lock, &old_irql, "remove all");
143 if (!list_empty(&cards)) {
144 card = list_entry(cards.next, udiva_card, list);
145 list_del(&card->list);
146 diva_os_leave_spin_lock(&ll_lock, &old_irql, "remove all");
147 diva_user_mode_idi_remove_adapter(card->Id);
148 diva_os_free(0, card);
149 goto rescan;
150 }
151 diva_os_leave_spin_lock(&ll_lock, &old_irql, "remove all");
152}
153
154/*
155 * DIDD notify callback
156 */
157static void *didd_callback(void *context, DESCRIPTOR *adapter,
158 int removal)
159{
160 if (adapter->type == IDI_DADAPTER) {
161 DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
162 return (NULL);
163 } else if (adapter->type == IDI_DIMAINT) {
164 if (removal) {
165 stop_dbg();
166 } else {
167 memcpy(&MAdapter, adapter, sizeof(MAdapter));
168 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
169 DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
170 }
171 } else if ((adapter->type > 0) && (adapter->type < 16)) { /* IDI Adapter */
172 if (removal) {
173 um_remove_card(adapter);
174 } else {
175 um_new_card(adapter);
176 }
177 }
178 return (NULL);
179}
180
181/*
182 * connect DIDD
183 */
184static int __init connect_didd(void)
185{
186 int x = 0;
187 int dadapter = 0;
188 IDI_SYNC_REQ req;
189 DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
190
191 DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
192
193 for (x = 0; x < MAX_DESCRIPTORS; x++) {
194 if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */
195 dadapter = 1;
196 memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
197 req.didd_notify.e.Req = 0;
198 req.didd_notify.e.Rc =
199 IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
200 req.didd_notify.info.callback = (void *)didd_callback;
201 req.didd_notify.info.context = NULL;
202 DAdapter.request((ENTITY *)&req);
203 if (req.didd_notify.e.Rc != 0xff) {
204 stop_dbg();
205 return (0);
206 }
207 notify_handle = req.didd_notify.info.handle;
208 } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
209 memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
210 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
211 DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
212 } else if ((DIDD_Table[x].type > 0)
213 && (DIDD_Table[x].type < 16)) { /* IDI Adapter found */
214 um_new_card(&DIDD_Table[x]);
215 }
216 }
217
218 if (!dadapter) {
219 stop_dbg();
220 }
221
222 return (dadapter);
223}
224
225/*
226 * Disconnect from DIDD
227 */
228static void __exit disconnect_didd(void)
229{
230 IDI_SYNC_REQ req;
231
232 stop_dbg();
233
234 req.didd_notify.e.Req = 0;
235 req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
236 req.didd_notify.info.handle = notify_handle;
237 DAdapter.request((ENTITY *)&req);
238}
239
240/*
241 * init
242 */
243int __init idifunc_init(void)
244{
245 diva_os_initialize_spin_lock(&ll_lock, "idifunc");
246
247 if (diva_user_mode_idi_init()) {
248 DBG_ERR(("init: init failed."));
249 return (0);
250 }
251
252 if (!connect_didd()) {
253 diva_user_mode_idi_finit();
254 DBG_ERR(("init: failed to connect to DIDD."));
255 return (0);
256 }
257 return (1);
258}
259
260/*
261 * finit
262 */
263void __exit idifunc_finit(void)
264{
265 diva_user_mode_idi_finit();
266 disconnect_didd();
267 remove_all_idi_proc();
268}
diff --git a/drivers/isdn/hardware/eicon/io.c b/drivers/isdn/hardware/eicon/io.c
deleted file mode 100644
index 8851ce580c23..000000000000
--- a/drivers/isdn/hardware/eicon/io.c
+++ /dev/null
@@ -1,852 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include "platform.h"
27#include "di_defs.h"
28#include "pc.h"
29#include "pr_pc.h"
30#include "divasync.h"
31#define MIPS_SCOM
32#include "pkmaint.h" /* pc_main.h, packed in os-dependent fashion */
33#include "di.h"
34#include "mi_pc.h"
35#include "io.h"
36extern ADAPTER *adapter[MAX_ADAPTER];
37extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
38void request(PISDN_ADAPTER, ENTITY *);
39static void pcm_req(PISDN_ADAPTER, ENTITY *);
40/* --------------------------------------------------------------------------
41 local functions
42 -------------------------------------------------------------------------- */
43#define ReqFunc(N) \
44 static void Request##N(ENTITY *e) \
45 { if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); }
46ReqFunc(0)
47ReqFunc(1)
48ReqFunc(2)
49ReqFunc(3)
50ReqFunc(4)
51ReqFunc(5)
52ReqFunc(6)
53ReqFunc(7)
54ReqFunc(8)
55ReqFunc(9)
56ReqFunc(10)
57ReqFunc(11)
58ReqFunc(12)
59ReqFunc(13)
60ReqFunc(14)
61ReqFunc(15)
62IDI_CALL Requests[MAX_ADAPTER] =
63{ &Request0, &Request1, &Request2, &Request3,
64 &Request4, &Request5, &Request6, &Request7,
65 &Request8, &Request9, &Request10, &Request11,
66 &Request12, &Request13, &Request14, &Request15
67};
68/*****************************************************************************/
69/*
70 This array should indicate all new services, that this version of XDI
71 is able to provide to his clients
72*/
73static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ + 1] = {
74 (DIVA_XDI_EXTENDED_FEATURES_VALID |
75 DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR |
76 DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS |
77#if defined(DIVA_IDI_RX_DMA)
78 DIVA_XDI_EXTENDED_FEATURE_CMA |
79 DIVA_XDI_EXTENDED_FEATURE_RX_DMA |
80 DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA |
81#endif
82 DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC),
83 0
84};
85/*****************************************************************************/
86void
87dump_xlog_buffer(PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc)
88{
89 dword logLen;
90 word *Xlog = xlogDesc->buf;
91 word logCnt = xlogDesc->cnt;
92 word logOut = xlogDesc->out / sizeof(*Xlog);
93 DBG_FTL(("%s: ************* XLOG recovery (%d) *************",
94 &IoAdapter->Name[0], (int)logCnt))
95 DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
96 for (; logCnt > 0; --logCnt)
97 {
98 if (!GET_WORD(&Xlog[logOut]))
99 {
100 if (--logCnt == 0)
101 break;
102 logOut = 0;
103 }
104 if (GET_WORD(&Xlog[logOut]) <= (logOut * sizeof(*Xlog)))
105 {
106 if (logCnt > 2)
107 {
108 DBG_FTL(("Possibly corrupted XLOG: %d entries left",
109 (int)logCnt))
110 }
111 break;
112 }
113 logLen = (dword)(GET_WORD(&Xlog[logOut]) - (logOut * sizeof(*Xlog)));
114 DBG_FTL_MXLOG(((char *)&Xlog[logOut + 1], (dword)(logLen - 2)))
115 logOut = (GET_WORD(&Xlog[logOut]) + 1) / sizeof(*Xlog);
116 }
117 DBG_FTL(("%s: ***************** end of XLOG *****************",
118 &IoAdapter->Name[0]))
119 }
120/*****************************************************************************/
121#if defined(XDI_USE_XLOG)
122static char *(ExceptionCauseTable[]) =
123{
124 "Interrupt",
125 "TLB mod /IBOUND",
126 "TLB load /DBOUND",
127 "TLB store",
128 "Address error load",
129 "Address error store",
130 "Instruction load bus error",
131 "Data load/store bus error",
132 "Syscall",
133 "Breakpoint",
134 "Reverd instruction",
135 "Coprocessor unusable",
136 "Overflow",
137 "TRAP",
138 "VCEI",
139 "Floating Point Exception",
140 "CP2",
141 "Reserved 17",
142 "Reserved 18",
143 "Reserved 19",
144 "Reserved 20",
145 "Reserved 21",
146 "Reserved 22",
147 "WATCH",
148 "Reserved 24",
149 "Reserved 25",
150 "Reserved 26",
151 "Reserved 27",
152 "Reserved 28",
153 "Reserved 29",
154 "Reserved 30",
155 "VCED"
156};
157#endif
158void
159dump_trap_frame(PISDN_ADAPTER IoAdapter, byte __iomem *exceptionFrame)
160{
161 MP_XCPTC __iomem *xcept = (MP_XCPTC __iomem *)exceptionFrame;
162 dword __iomem *regs;
163 regs = &xcept->regs[0];
164 DBG_FTL(("%s: ***************** CPU TRAPPED *****************",
165 &IoAdapter->Name[0]))
166 DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
167 DBG_FTL(("Cause: %s",
168 ExceptionCauseTable[(READ_DWORD(&xcept->cr) & 0x0000007c) >> 2]))
169 DBG_FTL(("sr 0x%08x cr 0x%08x epc 0x%08x vaddr 0x%08x",
170 READ_DWORD(&xcept->sr), READ_DWORD(&xcept->cr),
171 READ_DWORD(&xcept->epc), READ_DWORD(&xcept->vaddr)))
172 DBG_FTL(("zero 0x%08x at 0x%08x v0 0x%08x v1 0x%08x",
173 READ_DWORD(&regs[0]), READ_DWORD(&regs[1]),
174 READ_DWORD(&regs[2]), READ_DWORD(&regs[3])))
175 DBG_FTL(("a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x",
176 READ_DWORD(&regs[4]), READ_DWORD(&regs[5]),
177 READ_DWORD(&regs[6]), READ_DWORD(&regs[7])))
178 DBG_FTL(("t0 0x%08x t1 0x%08x t2 0x%08x t3 0x%08x",
179 READ_DWORD(&regs[8]), READ_DWORD(&regs[9]),
180 READ_DWORD(&regs[10]), READ_DWORD(&regs[11])))
181 DBG_FTL(("t4 0x%08x t5 0x%08x t6 0x%08x t7 0x%08x",
182 READ_DWORD(&regs[12]), READ_DWORD(&regs[13]),
183 READ_DWORD(&regs[14]), READ_DWORD(&regs[15])))
184 DBG_FTL(("s0 0x%08x s1 0x%08x s2 0x%08x s3 0x%08x",
185 READ_DWORD(&regs[16]), READ_DWORD(&regs[17]),
186 READ_DWORD(&regs[18]), READ_DWORD(&regs[19])))
187 DBG_FTL(("s4 0x%08x s5 0x%08x s6 0x%08x s7 0x%08x",
188 READ_DWORD(&regs[20]), READ_DWORD(&regs[21]),
189 READ_DWORD(&regs[22]), READ_DWORD(&regs[23])))
190 DBG_FTL(("t8 0x%08x t9 0x%08x k0 0x%08x k1 0x%08x",
191 READ_DWORD(&regs[24]), READ_DWORD(&regs[25]),
192 READ_DWORD(&regs[26]), READ_DWORD(&regs[27])))
193 DBG_FTL(("gp 0x%08x sp 0x%08x s8 0x%08x ra 0x%08x",
194 READ_DWORD(&regs[28]), READ_DWORD(&regs[29]),
195 READ_DWORD(&regs[30]), READ_DWORD(&regs[31])))
196 DBG_FTL(("md 0x%08x|%08x resvd 0x%08x class 0x%08x",
197 READ_DWORD(&xcept->mdhi), READ_DWORD(&xcept->mdlo),
198 READ_DWORD(&xcept->reseverd), READ_DWORD(&xcept->xclass)))
199 }
200/* --------------------------------------------------------------------------
201 Real XDI Request function
202 -------------------------------------------------------------------------- */
203void request(PISDN_ADAPTER IoAdapter, ENTITY *e)
204{
205 byte i;
206 diva_os_spin_lock_magic_t irql;
207/*
208 * if the Req field in the entity structure is 0,
209 * we treat this request as a special function call
210 */
211 if (!e->Req)
212 {
213 IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e;
214 switch (e->Rc)
215 {
216#if defined(DIVA_IDI_RX_DMA)
217 case IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION: {
218 diva_xdi_dma_descriptor_operation_t *pI = \
219 &syncReq->xdi_dma_descriptor_operation.info;
220 if (!IoAdapter->dma_map) {
221 pI->operation = -1;
222 pI->descriptor_number = -1;
223 return;
224 }
225 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op");
226 if (pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC) {
227 pI->descriptor_number = diva_alloc_dma_map_entry(\
228 (struct _diva_dma_map_entry *)IoAdapter->dma_map);
229 if (pI->descriptor_number >= 0) {
230 dword dma_magic;
231 void *local_addr;
232 diva_get_dma_map_entry(\
233 (struct _diva_dma_map_entry *)IoAdapter->dma_map,
234 pI->descriptor_number,
235 &local_addr, &dma_magic);
236 pI->descriptor_address = local_addr;
237 pI->descriptor_magic = dma_magic;
238 pI->operation = 0;
239 } else {
240 pI->operation = -1;
241 }
242 } else if ((pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE) &&
243 (pI->descriptor_number >= 0)) {
244 diva_free_dma_map_entry((struct _diva_dma_map_entry *)IoAdapter->dma_map,
245 pI->descriptor_number);
246 pI->descriptor_number = -1;
247 pI->operation = 0;
248 } else {
249 pI->descriptor_number = -1;
250 pI->operation = -1;
251 }
252 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op");
253 } return;
254#endif
255 case IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER: {
256 diva_xdi_get_logical_adapter_number_s_t *pI = \
257 &syncReq->xdi_logical_adapter_number.info;
258 pI->logical_adapter_number = IoAdapter->ANum;
259 pI->controller = IoAdapter->ControllerNumber;
260 pI->total_controllers = IoAdapter->Properties.Adapters;
261 } return;
262 case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS: {
263 diva_xdi_get_capi_parameters_t prms, *pI = &syncReq->xdi_capi_prms.info;
264 memset(&prms, 0x00, sizeof(prms));
265 prms.structure_length = min_t(size_t, sizeof(prms), pI->structure_length);
266 memset(pI, 0x00, pI->structure_length);
267 prms.flag_dynamic_l1_down = (IoAdapter->capi_cfg.cfg_1 & \
268 DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? 1 : 0;
269 prms.group_optimization_enabled = (IoAdapter->capi_cfg.cfg_1 & \
270 DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) ? 1 : 0;
271 memcpy(pI, &prms, prms.structure_length);
272 } return;
273 case IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR:
274 syncReq->xdi_sdram_bar.info.bar = IoAdapter->sdram_bar;
275 return;
276 case IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES: {
277 dword i;
278 diva_xdi_get_extended_xdi_features_t *pI =\
279 &syncReq->xdi_extended_features.info;
280 pI->buffer_length_in_bytes &= ~0x80000000;
281 if (pI->buffer_length_in_bytes && pI->features) {
282 memset(pI->features, 0x00, pI->buffer_length_in_bytes);
283 }
284 for (i = 0; ((pI->features) && (i < pI->buffer_length_in_bytes) &&
285 (i < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ)); i++) {
286 pI->features[i] = extended_xdi_features[i];
287 }
288 if ((pI->buffer_length_in_bytes < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ) ||
289 (!pI->features)) {
290 pI->buffer_length_in_bytes =\
291 (0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ);
292 }
293 } return;
294 case IDI_SYNC_REQ_XDI_GET_STREAM:
295 if (IoAdapter) {
296 diva_xdi_provide_istream_info(&IoAdapter->a,
297 &syncReq->xdi_stream_info.info);
298 } else {
299 syncReq->xdi_stream_info.info.provided_service = 0;
300 }
301 return;
302 case IDI_SYNC_REQ_GET_NAME:
303 if (IoAdapter)
304 {
305 strcpy(&syncReq->GetName.name[0], IoAdapter->Name);
306 DBG_TRC(("xdi: Adapter %d / Name '%s'",
307 IoAdapter->ANum, IoAdapter->Name))
308 return;
309 }
310 syncReq->GetName.name[0] = '\0';
311 break;
312 case IDI_SYNC_REQ_GET_SERIAL:
313 if (IoAdapter)
314 {
315 syncReq->GetSerial.serial = IoAdapter->serialNo;
316 DBG_TRC(("xdi: Adapter %d / SerialNo %ld",
317 IoAdapter->ANum, IoAdapter->serialNo))
318 return;
319 }
320 syncReq->GetSerial.serial = 0;
321 break;
322 case IDI_SYNC_REQ_GET_CARDTYPE:
323 if (IoAdapter)
324 {
325 syncReq->GetCardType.cardtype = IoAdapter->cardType;
326 DBG_TRC(("xdi: Adapter %d / CardType %ld",
327 IoAdapter->ANum, IoAdapter->cardType))
328 return;
329 }
330 syncReq->GetCardType.cardtype = 0;
331 break;
332 case IDI_SYNC_REQ_GET_XLOG:
333 if (IoAdapter)
334 {
335 pcm_req(IoAdapter, e);
336 return;
337 }
338 e->Ind = 0;
339 break;
340 case IDI_SYNC_REQ_GET_DBG_XLOG:
341 if (IoAdapter)
342 {
343 pcm_req(IoAdapter, e);
344 return;
345 }
346 e->Ind = 0;
347 break;
348 case IDI_SYNC_REQ_GET_FEATURES:
349 if (IoAdapter)
350 {
351 syncReq->GetFeatures.features =
352 (unsigned short)IoAdapter->features;
353 return;
354 }
355 syncReq->GetFeatures.features = 0;
356 break;
357 case IDI_SYNC_REQ_PORTDRV_HOOK:
358 if (IoAdapter)
359 {
360 DBG_TRC(("Xdi:IDI_SYNC_REQ_PORTDRV_HOOK - ignored"))
361 return;
362 }
363 break;
364 }
365 if (IoAdapter)
366 {
367 return;
368 }
369 }
370 DBG_TRC(("xdi: Id 0x%x / Req 0x%x / Rc 0x%x", e->Id, e->Req, e->Rc))
371 if (!IoAdapter)
372 {
373 DBG_FTL(("xdi: uninitialized Adapter used - ignore request"))
374 return;
375 }
376 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
377/*
378 * assign an entity
379 */
380 if (!(e->Id & 0x1f))
381 {
382 if (IoAdapter->e_count >= IoAdapter->e_max)
383 {
384 DBG_FTL(("xdi: all Ids in use (max=%d) --> Req ignored",
385 IoAdapter->e_max))
386 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
387 return;
388 }
389/*
390 * find a new free id
391 */
392 for (i = 1; IoAdapter->e_tbl[i].e; ++i);
393 IoAdapter->e_tbl[i].e = e;
394 IoAdapter->e_count++;
395 e->No = (byte)i;
396 e->More = 0;
397 e->RCurrent = 0xff;
398 }
399 else
400 {
401 i = e->No;
402 }
403/*
404 * if the entity is still busy, ignore the request call
405 */
406 if (e->More & XBUSY)
407 {
408 DBG_FTL(("xdi: Id 0x%x busy --> Req 0x%x ignored", e->Id, e->Req))
409 if (!IoAdapter->trapped && IoAdapter->trapFnc)
410 {
411 IoAdapter->trapFnc(IoAdapter);
412 /*
413 Firs trap, also notify user if supported
414 */
415 if (IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
416 (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
417 }
418 }
419 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
420 return;
421 }
422/*
423 * initialize transmit status variables
424 */
425 e->More |= XBUSY;
426 e->More &= ~XMOREF;
427 e->XCurrent = 0;
428 e->XOffset = 0;
429/*
430 * queue this entity in the adapter request queue
431 */
432 IoAdapter->e_tbl[i].next = 0;
433 if (IoAdapter->head)
434 {
435 IoAdapter->e_tbl[IoAdapter->tail].next = i;
436 IoAdapter->tail = i;
437 }
438 else
439 {
440 IoAdapter->head = i;
441 IoAdapter->tail = i;
442 }
443/*
444 * queue the DPC to process the request
445 */
446 diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
447 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
448}
449/* ---------------------------------------------------------------------
450 Main DPC routine
451 --------------------------------------------------------------------- */
452void DIDpcRoutine(struct _diva_os_soft_isr *psoft_isr, void *Context) {
453 PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)Context;
454 ADAPTER *a = &IoAdapter->a;
455 diva_os_atomic_t *pin_dpc = &IoAdapter->in_dpc;
456 if (diva_os_atomic_increment(pin_dpc) == 1) {
457 do {
458 if (IoAdapter->tst_irq(a))
459 {
460 if (!IoAdapter->Unavailable)
461 IoAdapter->dpc(a);
462 IoAdapter->clr_irq(a);
463 }
464 IoAdapter->out(a);
465 } while (diva_os_atomic_decrement(pin_dpc) > 0);
466 /* ----------------------------------------------------------------
467 Look for XLOG request (cards with indirect addressing)
468 ---------------------------------------------------------------- */
469 if (IoAdapter->pcm_pending) {
470 struct pc_maint *pcm;
471 diva_os_spin_lock_magic_t OldIrql;
472 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
473 &OldIrql,
474 "data_dpc");
475 pcm = (struct pc_maint *)IoAdapter->pcm_data;
476 switch (IoAdapter->pcm_pending) {
477 case 1: /* ask card for XLOG */
478 a->ram_out(a, &IoAdapter->pcm->rc, 0);
479 a->ram_out(a, &IoAdapter->pcm->req, pcm->req);
480 IoAdapter->pcm_pending = 2;
481 break;
482 case 2: /* Try to get XLOG from the card */
483 if ((int)(a->ram_in(a, &IoAdapter->pcm->rc))) {
484 a->ram_in_buffer(a, IoAdapter->pcm, pcm, sizeof(*pcm));
485 IoAdapter->pcm_pending = 3;
486 }
487 break;
488 case 3: /* let XDI recovery XLOG */
489 break;
490 }
491 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
492 &OldIrql,
493 "data_dpc");
494 }
495 /* ---------------------------------------------------------------- */
496 }
497}
498/* --------------------------------------------------------------------------
499 XLOG interface
500 -------------------------------------------------------------------------- */
501static void
502pcm_req(PISDN_ADAPTER IoAdapter, ENTITY *e)
503{
504 diva_os_spin_lock_magic_t OldIrql;
505 int i, rc;
506 ADAPTER *a = &IoAdapter->a;
507 struct pc_maint *pcm = (struct pc_maint *)&e->Ind;
508/*
509 * special handling of I/O based card interface
510 * the memory access isn't an atomic operation !
511 */
512 if (IoAdapter->Properties.Card == CARD_MAE)
513 {
514 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
515 &OldIrql,
516 "data_pcm_1");
517 IoAdapter->pcm_data = (void *)pcm;
518 IoAdapter->pcm_pending = 1;
519 diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
520 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
521 &OldIrql,
522 "data_pcm_1");
523 for (rc = 0, i = (IoAdapter->trapped ? 3000 : 250); !rc && (i > 0); --i)
524 {
525 diva_os_sleep(1);
526 if (IoAdapter->pcm_pending == 3) {
527 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
528 &OldIrql,
529 "data_pcm_3");
530 IoAdapter->pcm_pending = 0;
531 IoAdapter->pcm_data = NULL;
532 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
533 &OldIrql,
534 "data_pcm_3");
535 return;
536 }
537 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
538 &OldIrql,
539 "data_pcm_2");
540 diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
541 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
542 &OldIrql,
543 "data_pcm_2");
544 }
545 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
546 &OldIrql,
547 "data_pcm_4");
548 IoAdapter->pcm_pending = 0;
549 IoAdapter->pcm_data = NULL;
550 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
551 &OldIrql,
552 "data_pcm_4");
553 goto Trapped;
554 }
555/*
556 * memory based shared ram is accessible from different
557 * processors without disturbing concurrent processes.
558 */
559 a->ram_out(a, &IoAdapter->pcm->rc, 0);
560 a->ram_out(a, &IoAdapter->pcm->req, pcm->req);
561 for (i = (IoAdapter->trapped ? 3000 : 250); --i > 0;)
562 {
563 diva_os_sleep(1);
564 rc = (int)(a->ram_in(a, &IoAdapter->pcm->rc));
565 if (rc)
566 {
567 a->ram_in_buffer(a, IoAdapter->pcm, pcm, sizeof(*pcm));
568 return;
569 }
570 }
571Trapped:
572 if (IoAdapter->trapFnc)
573 {
574 int trapped = IoAdapter->trapped;
575 IoAdapter->trapFnc(IoAdapter);
576 /*
577 Firs trap, also notify user if supported
578 */
579 if (!trapped && IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
580 (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
581 }
582 }
583}
584/*------------------------------------------------------------------*/
585/* ram access functions for memory mapped cards */
586/*------------------------------------------------------------------*/
587byte mem_in(ADAPTER *a, void *addr)
588{
589 byte val;
590 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
591 val = READ_BYTE(Base + (unsigned long)addr);
592 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
593 return (val);
594}
595word mem_inw(ADAPTER *a, void *addr)
596{
597 word val;
598 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
599 val = READ_WORD((Base + (unsigned long)addr));
600 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
601 return (val);
602}
603void mem_in_dw(ADAPTER *a, void *addr, dword *data, int dwords)
604{
605 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
606 while (dwords--) {
607 *data++ = READ_DWORD((Base + (unsigned long)addr));
608 addr += 4;
609 }
610 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
611}
612void mem_in_buffer(ADAPTER *a, void *addr, void *buffer, word length)
613{
614 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
615 memcpy_fromio(buffer, (Base + (unsigned long)addr), length);
616 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
617}
618void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
619{
620 PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io;
621 IoAdapter->RBuffer.length = mem_inw(a, &RBuffer->length);
622 mem_in_buffer(a, RBuffer->P, IoAdapter->RBuffer.P,
623 IoAdapter->RBuffer.length);
624 e->RBuffer = (DBUFFER *)&IoAdapter->RBuffer;
625}
626void mem_out(ADAPTER *a, void *addr, byte data)
627{
628 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
629 WRITE_BYTE(Base + (unsigned long)addr, data);
630 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
631}
632void mem_outw(ADAPTER *a, void *addr, word data)
633{
634 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
635 WRITE_WORD((Base + (unsigned long)addr), data);
636 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
637}
638void mem_out_dw(ADAPTER *a, void *addr, const dword *data, int dwords)
639{
640 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
641 while (dwords--) {
642 WRITE_DWORD((Base + (unsigned long)addr), *data);
643 addr += 4;
644 data++;
645 }
646 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
647}
648void mem_out_buffer(ADAPTER *a, void *addr, void *buffer, word length)
649{
650 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
651 memcpy_toio((Base + (unsigned long)addr), buffer, length);
652 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
653}
654void mem_inc(ADAPTER *a, void *addr)
655{
656 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
657 byte x = READ_BYTE(Base + (unsigned long)addr);
658 WRITE_BYTE(Base + (unsigned long)addr, x + 1);
659 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
660}
661/*------------------------------------------------------------------*/
662/* ram access functions for io-mapped cards */
663/*------------------------------------------------------------------*/
664byte io_in(ADAPTER *a, void *adr)
665{
666 byte val;
667 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
668 outppw(Port + 4, (word)(unsigned long)adr);
669 val = inpp(Port);
670 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
671 return (val);
672}
673word io_inw(ADAPTER *a, void *adr)
674{
675 word val;
676 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
677 outppw(Port + 4, (word)(unsigned long)adr);
678 val = inppw(Port);
679 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
680 return (val);
681}
682void io_in_buffer(ADAPTER *a, void *adr, void *buffer, word len)
683{
684 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
685 byte *P = (byte *)buffer;
686 if ((long)adr & 1) {
687 outppw(Port + 4, (word)(unsigned long)adr);
688 *P = inpp(Port);
689 P++;
690 adr = ((byte *) adr) + 1;
691 len--;
692 if (!len) {
693 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
694 return;
695 }
696 }
697 outppw(Port + 4, (word)(unsigned long)adr);
698 inppw_buffer(Port, P, len + 1);
699 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
700}
701void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
702{
703 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
704 outppw(Port + 4, (word)(unsigned long)RBuffer);
705 ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port);
706 inppw_buffer(Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
707 e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer);
708 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
709}
710void io_out(ADAPTER *a, void *adr, byte data)
711{
712 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
713 outppw(Port + 4, (word)(unsigned long)adr);
714 outpp(Port, data);
715 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
716}
717void io_outw(ADAPTER *a, void *adr, word data)
718{
719 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
720 outppw(Port + 4, (word)(unsigned long)adr);
721 outppw(Port, data);
722 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
723}
724void io_out_buffer(ADAPTER *a, void *adr, void *buffer, word len)
725{
726 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
727 byte *P = (byte *)buffer;
728 if ((long)adr & 1) {
729 outppw(Port + 4, (word)(unsigned long)adr);
730 outpp(Port, *P);
731 P++;
732 adr = ((byte *) adr) + 1;
733 len--;
734 if (!len) {
735 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
736 return;
737 }
738 }
739 outppw(Port + 4, (word)(unsigned long)adr);
740 outppw_buffer(Port, P, len + 1);
741 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
742}
743void io_inc(ADAPTER *a, void *adr)
744{
745 byte x;
746 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
747 outppw(Port + 4, (word)(unsigned long)adr);
748 x = inpp(Port);
749 outppw(Port + 4, (word)(unsigned long)adr);
750 outpp(Port, x + 1);
751 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
752}
753/*------------------------------------------------------------------*/
754/* OS specific functions related to queuing of entities */
755/*------------------------------------------------------------------*/
756void free_entity(ADAPTER *a, byte e_no)
757{
758 PISDN_ADAPTER IoAdapter;
759 diva_os_spin_lock_magic_t irql;
760 IoAdapter = (PISDN_ADAPTER) a->io;
761 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_free");
762 IoAdapter->e_tbl[e_no].e = NULL;
763 IoAdapter->e_count--;
764 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_free");
765}
766void assign_queue(ADAPTER *a, byte e_no, word ref)
767{
768 PISDN_ADAPTER IoAdapter;
769 diva_os_spin_lock_magic_t irql;
770 IoAdapter = (PISDN_ADAPTER) a->io;
771 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_assign");
772 IoAdapter->e_tbl[e_no].assign_ref = ref;
773 IoAdapter->e_tbl[e_no].next = (byte)IoAdapter->assign;
774 IoAdapter->assign = e_no;
775 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_assign");
776}
777byte get_assign(ADAPTER *a, word ref)
778{
779 PISDN_ADAPTER IoAdapter;
780 diva_os_spin_lock_magic_t irql;
781 byte e_no;
782 IoAdapter = (PISDN_ADAPTER) a->io;
783 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
784 &irql,
785 "data_assign_get");
786 for (e_no = (byte)IoAdapter->assign;
787 e_no && IoAdapter->e_tbl[e_no].assign_ref != ref;
788 e_no = IoAdapter->e_tbl[e_no].next);
789 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
790 &irql,
791 "data_assign_get");
792 return e_no;
793}
794void req_queue(ADAPTER *a, byte e_no)
795{
796 PISDN_ADAPTER IoAdapter;
797 diva_os_spin_lock_magic_t irql;
798 IoAdapter = (PISDN_ADAPTER) a->io;
799 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_q");
800 IoAdapter->e_tbl[e_no].next = 0;
801 if (IoAdapter->head) {
802 IoAdapter->e_tbl[IoAdapter->tail].next = e_no;
803 IoAdapter->tail = e_no;
804 }
805 else {
806 IoAdapter->head = e_no;
807 IoAdapter->tail = e_no;
808 }
809 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_q");
810}
811byte look_req(ADAPTER *a)
812{
813 PISDN_ADAPTER IoAdapter;
814 IoAdapter = (PISDN_ADAPTER) a->io;
815 return ((byte)IoAdapter->head);
816}
817void next_req(ADAPTER *a)
818{
819 PISDN_ADAPTER IoAdapter;
820 diva_os_spin_lock_magic_t irql;
821 IoAdapter = (PISDN_ADAPTER) a->io;
822 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_next");
823 IoAdapter->head = IoAdapter->e_tbl[IoAdapter->head].next;
824 if (!IoAdapter->head) IoAdapter->tail = 0;
825 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_next");
826}
827/*------------------------------------------------------------------*/
828/* memory map functions */
829/*------------------------------------------------------------------*/
830ENTITY *entity_ptr(ADAPTER *a, byte e_no)
831{
832 PISDN_ADAPTER IoAdapter;
833 IoAdapter = (PISDN_ADAPTER)a->io;
834 return (IoAdapter->e_tbl[e_no].e);
835}
836void *PTR_X(ADAPTER *a, ENTITY *e)
837{
838 return ((void *) e->X);
839}
840void *PTR_R(ADAPTER *a, ENTITY *e)
841{
842 return ((void *) e->R);
843}
844void *PTR_P(ADAPTER *a, ENTITY *e, void *P)
845{
846 return P;
847}
848void CALLBACK(ADAPTER *a, ENTITY *e)
849{
850 if (e && e->callback)
851 e->callback(e);
852}
diff --git a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h
deleted file mode 100644
index 01deced18ab8..000000000000
--- a/drivers/isdn/hardware/eicon/io.h
+++ /dev/null
@@ -1,308 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_XDI_COMMON_IO_H_INC__ /* { */
27#define __DIVA_XDI_COMMON_IO_H_INC__
28/*
29 maximum = 16 adapters
30*/
31#define DI_MAX_LINKS MAX_ADAPTER
32#define ISDN_MAX_NUM_LEN 60
33/* --------------------------------------------------------------------------
34 structure for quadro card management (obsolete for
35 systems that do provide per card load event)
36 -------------------------------------------------------------------------- */
37typedef struct {
38 dword Num;
39 DEVICE_NAME DeviceName[4];
40 PISDN_ADAPTER QuadroAdapter[4];
41} ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY;
42/* --------------------------------------------------------------------------
43 Special OS memory support structures
44 -------------------------------------------------------------------------- */
45#define MAX_MAPPED_ENTRIES 8
46typedef struct {
47 void *Address;
48 dword Length;
49} ADAPTER_MEMORY;
50/* --------------------------------------------------------------------------
51 Configuration of XDI clients carried by XDI
52 -------------------------------------------------------------------------- */
53#define DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON 0x01
54#define DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON 0x02
55typedef struct _diva_xdi_capi_cfg {
56 byte cfg_1;
57} diva_xdi_capi_cfg_t;
58/* --------------------------------------------------------------------------
59 Main data structure kept per adapter
60 -------------------------------------------------------------------------- */
61struct _ISDN_ADAPTER {
62 void (*DIRequest)(PISDN_ADAPTER, ENTITY *);
63 int State; /* from NT4 1.srv, a good idea, but a poor achievement */
64 int Initialized;
65 int RegisteredWithDidd;
66 int Unavailable; /* callback function possible? */
67 int ResourcesClaimed;
68 int PnpBiosConfigUsed;
69 dword Logging;
70 dword features;
71 char ProtocolIdString[80];
72 /*
73 remember mapped memory areas
74 */
75 ADAPTER_MEMORY MappedMemory[MAX_MAPPED_ENTRIES];
76 CARD_PROPERTIES Properties;
77 dword cardType;
78 dword protocol_id; /* configured protocol identifier */
79 char protocol_name[8]; /* readable name of protocol */
80 dword BusType;
81 dword BusNumber;
82 dword slotNumber;
83 dword slotId;
84 dword ControllerNumber; /* for QUADRO cards only */
85 PISDN_ADAPTER MultiMaster; /* for 4-BRI card only - use MultiMaster or QuadroList */
86 PADAPTER_LIST_ENTRY QuadroList; /* for QUADRO card only */
87 PDEVICE_OBJECT DeviceObject;
88 dword DeviceId;
89 diva_os_adapter_irq_info_t irq_info;
90 dword volatile IrqCount;
91 int trapped;
92 dword DspCodeBaseAddr;
93 dword MaxDspCodeSize;
94 dword downloadAddr;
95 dword DspCodeBaseAddrTable[4]; /* add. for MultiMaster */
96 dword MaxDspCodeSizeTable[4]; /* add. for MultiMaster */
97 dword downloadAddrTable[4]; /* add. for MultiMaster */
98 dword MemoryBase;
99 dword MemorySize;
100 byte __iomem *Address;
101 byte __iomem *Config;
102 byte __iomem *Control;
103 byte __iomem *reset;
104 byte __iomem *port;
105 byte __iomem *ram;
106 byte __iomem *cfg;
107 byte __iomem *prom;
108 byte __iomem *ctlReg;
109 struct pc_maint *pcm;
110 diva_os_dependent_devica_name_t os_name;
111 byte Name[32];
112 dword serialNo;
113 dword ANum;
114 dword ArchiveType; /* ARCHIVE_TYPE_NONE ..._SINGLE ..._USGEN ..._MULTI */
115 char *ProtocolSuffix; /* internal protocolfile table */
116 char Archive[32];
117 char Protocol[32];
118 char AddDownload[32]; /* Dsp- or other additional download files */
119 char Oad1[ISDN_MAX_NUM_LEN];
120 char Osa1[ISDN_MAX_NUM_LEN];
121 char Oad2[ISDN_MAX_NUM_LEN];
122 char Osa2[ISDN_MAX_NUM_LEN];
123 char Spid1[ISDN_MAX_NUM_LEN];
124 char Spid2[ISDN_MAX_NUM_LEN];
125 byte nosig;
126 byte BriLayer2LinkCount; /* amount of TEI's that adapter will support in P2MP mode */
127 dword Channels;
128 dword tei;
129 dword nt2;
130 dword TerminalCount;
131 dword WatchDog;
132 dword Permanent;
133 dword BChMask; /* B channel mask for unchannelized modes */
134 dword StableL2;
135 dword DidLen;
136 dword NoOrderCheck;
137 dword ForceLaw; /* VoiceCoding - default:0, a-law: 1, my-law: 2 */
138 dword SigFlags;
139 dword LowChannel;
140 dword NoHscx30;
141 dword ProtVersion;
142 dword crc4;
143 dword L1TristateOrQsig; /* enable Layer 1 Tristate (bit 2)Or Qsig params (bit 0,1)*/
144 dword InitialDspInfo;
145 dword ModemGuardTone;
146 dword ModemMinSpeed;
147 dword ModemMaxSpeed;
148 dword ModemOptions;
149 dword ModemOptions2;
150 dword ModemNegotiationMode;
151 dword ModemModulationsMask;
152 dword ModemTransmitLevel;
153 dword FaxOptions;
154 dword FaxMaxSpeed;
155 dword Part68LevelLimiter;
156 dword UsEktsNumCallApp;
157 byte UsEktsFeatAddConf;
158 byte UsEktsFeatRemoveConf;
159 byte UsEktsFeatCallTransfer;
160 byte UsEktsFeatMsgWaiting;
161 byte QsigDialect;
162 byte ForceVoiceMailAlert;
163 byte DisableAutoSpid;
164 byte ModemCarrierWaitTimeSec;
165 byte ModemCarrierLossWaitTimeTenthSec;
166 byte PiafsLinkTurnaroundInFrames;
167 byte DiscAfterProgress;
168 byte AniDniLimiter[3];
169 byte TxAttenuation; /* PRI/E1 only: attenuate TX signal */
170 word QsigFeatures;
171 dword GenerateRingtone;
172 dword SupplementaryServicesFeatures;
173 dword R2Dialect;
174 dword R2CasOptions;
175 dword FaxV34Options;
176 dword DisabledDspMask;
177 dword AdapterTestMask;
178 dword DspImageLength;
179 word AlertToIn20mSecTicks;
180 word ModemEyeSetup;
181 byte R2CtryLength;
182 byte CCBSRelTimer;
183 byte *PcCfgBufferFile;/* flexible parameter via file */
184 byte *PcCfgBuffer; /* flexible parameter via multistring */
185 diva_os_dump_file_t dump_file; /* dump memory to file at lowest irq level */
186 diva_os_board_trace_t board_trace; /* traces from the board */
187 diva_os_spin_lock_t isr_spin_lock;
188 diva_os_spin_lock_t data_spin_lock;
189 diva_os_soft_isr_t req_soft_isr;
190 diva_os_soft_isr_t isr_soft_isr;
191 diva_os_atomic_t in_dpc;
192 PBUFFER RBuffer; /* Copy of receive lookahead buffer */
193 word e_max;
194 word e_count;
195 E_INFO *e_tbl;
196 word assign; /* list of pending ASSIGNs */
197 word head; /* head of request queue */
198 word tail; /* tail of request queue */
199 ADAPTER a; /* not a separate structure */
200 void (*out)(ADAPTER *a);
201 byte (*dpc)(ADAPTER *a);
202 byte (*tst_irq)(ADAPTER *a);
203 void (*clr_irq)(ADAPTER *a);
204 int (*load)(PISDN_ADAPTER);
205 int (*mapmem)(PISDN_ADAPTER);
206 int (*chkIrq)(PISDN_ADAPTER);
207 void (*disIrq)(PISDN_ADAPTER);
208 void (*start)(PISDN_ADAPTER);
209 void (*stop)(PISDN_ADAPTER);
210 void (*rstFnc)(PISDN_ADAPTER);
211 void (*trapFnc)(PISDN_ADAPTER);
212 dword (*DetectDsps)(PISDN_ADAPTER);
213 void (*os_trap_nfy_Fnc)(PISDN_ADAPTER, dword);
214 diva_os_isr_callback_t diva_isr_handler;
215 dword sdram_bar; /* must be 32 bit */
216 dword fpga_features;
217 volatile int pcm_pending;
218 volatile void *pcm_data;
219 diva_xdi_capi_cfg_t capi_cfg;
220 dword tasks;
221 void *dma_map;
222 int (*DivaAdapterTestProc)(PISDN_ADAPTER);
223 void *AdapterTestMemoryStart;
224 dword AdapterTestMemoryLength;
225 const byte *cfg_lib_memory_init;
226 dword cfg_lib_memory_init_length;
227};
228/* ---------------------------------------------------------------------
229 Entity table
230 --------------------------------------------------------------------- */
231struct e_info_s {
232 ENTITY *e;
233 byte next; /* chaining index */
234 word assign_ref; /* assign reference */
235};
236/* ---------------------------------------------------------------------
237 S-cards shared ram structure for loading
238 --------------------------------------------------------------------- */
239struct s_load {
240 byte ctrl;
241 byte card;
242 byte msize;
243 byte fill0;
244 word ebit;
245 word elocl;
246 word eloch;
247 byte reserved[20];
248 word signature;
249 byte fill[224];
250 byte b[256];
251};
252#define PR_RAM ((struct pr_ram *)0)
253#define RAM ((struct dual *)0)
254/* ---------------------------------------------------------------------
255 platform specific conversions
256 --------------------------------------------------------------------- */
257extern void *PTR_P(ADAPTER *a, ENTITY *e, void *P);
258extern void *PTR_X(ADAPTER *a, ENTITY *e);
259extern void *PTR_R(ADAPTER *a, ENTITY *e);
260extern void CALLBACK(ADAPTER *a, ENTITY *e);
261extern void set_ram(void **adr_ptr);
262/* ---------------------------------------------------------------------
263 ram access functions for io mapped cards
264 --------------------------------------------------------------------- */
265byte io_in(ADAPTER *a, void *adr);
266word io_inw(ADAPTER *a, void *adr);
267void io_in_buffer(ADAPTER *a, void *adr, void *P, word length);
268void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
269void io_out(ADAPTER *a, void *adr, byte data);
270void io_outw(ADAPTER *a, void *adr, word data);
271void io_out_buffer(ADAPTER *a, void *adr, void *P, word length);
272void io_inc(ADAPTER *a, void *adr);
273void bri_in_buffer(PISDN_ADAPTER IoAdapter, dword Pos,
274 void *Buf, dword Len);
275int bri_out_buffer(PISDN_ADAPTER IoAdapter, dword Pos,
276 void *Buf, dword Len, int Verify);
277/* ---------------------------------------------------------------------
278 ram access functions for memory mapped cards
279 --------------------------------------------------------------------- */
280byte mem_in(ADAPTER *a, void *adr);
281word mem_inw(ADAPTER *a, void *adr);
282void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
283void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
284void mem_out(ADAPTER *a, void *adr, byte data);
285void mem_outw(ADAPTER *a, void *adr, word data);
286void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
287void mem_inc(ADAPTER *a, void *adr);
288void mem_in_dw(ADAPTER *a, void *addr, dword *data, int dwords);
289void mem_out_dw(ADAPTER *a, void *addr, const dword *data, int dwords);
290/* ---------------------------------------------------------------------
291 functions exported by io.c
292 --------------------------------------------------------------------- */
293extern IDI_CALL Requests[MAX_ADAPTER];
294extern void DIDpcRoutine(struct _diva_os_soft_isr *psoft_isr,
295 void *context);
296extern void request(PISDN_ADAPTER, ENTITY *);
297/* ---------------------------------------------------------------------
298 trapFn helpers, used to recover debug trace from dead card
299 --------------------------------------------------------------------- */
300typedef struct {
301 word *buf;
302 word cnt;
303 word out;
304} Xdesc;
305extern void dump_trap_frame(PISDN_ADAPTER IoAdapter, byte __iomem *exception);
306extern void dump_xlog_buffer(PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc);
307/* --------------------------------------------------------------------- */
308#endif /* } __DIVA_XDI_COMMON_IO_H_INC__ */
diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c
deleted file mode 100644
index 045bda5c839f..000000000000
--- a/drivers/isdn/hardware/eicon/istream.c
+++ /dev/null
@@ -1,226 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include "platform.h"
27#if defined(DIVA_ISTREAM) /* { */
28#include "pc.h"
29#include "pr_pc.h"
30#include "di_defs.h"
31#include "divasync.h"
32#include "di.h"
33#if !defined USE_EXTENDED_DEBUGS
34#include "dimaint.h"
35#else
36#define dprintf
37#endif
38#include "dfifo.h"
39int diva_istream_write(void *context,
40 int Id,
41 void *data,
42 int length,
43 int final,
44 byte usr1,
45 byte usr2);
46int diva_istream_read(void *context,
47 int Id,
48 void *data,
49 int max_length,
50 int *final,
51 byte *usr1,
52 byte *usr2);
53/* -------------------------------------------------------------------
54 Does provide iStream interface to the client
55 ------------------------------------------------------------------- */
56void diva_xdi_provide_istream_info(ADAPTER *a,
57 diva_xdi_stream_interface_t *pi) {
58 pi->provided_service = 0;
59}
60/* ------------------------------------------------------------------
61 Does write the data from caller's buffer to the card's
62 stream interface.
63 If synchronous service was requested, then function
64 does return amount of data written to stream.
65 'final' does indicate that piece of data to be written is
66 final part of frame (necessary only by structured datatransfer)
67 return 0 if zero lengh packet was written
68 return -1 if stream is full
69 ------------------------------------------------------------------ */
70int diva_istream_write(void *context,
71 int Id,
72 void *data,
73 int length,
74 int final,
75 byte usr1,
76 byte usr2) {
77 ADAPTER *a = (ADAPTER *)context;
78 int written = 0, to_write = -1;
79 char tmp[4];
80 byte *data_ptr = (byte *)data;
81 for (;;) {
82 a->ram_in_dw(a,
83#ifdef PLATFORM_GT_32BIT
84 ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
85#else
86 (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
87#endif
88 (dword *)&tmp[0],
89 1);
90 if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */
91 if (to_write < 0)
92 return (-1); /* was not able to write */
93 break; /* only part of message was written */
94 }
95 to_write = min(length, DIVA_DFIFO_DATA_SZ);
96 if (to_write) {
97 a->ram_out_buffer(a,
98#ifdef PLATFORM_GT_32BIT
99 ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id] + 4),
100#else
101 (void *)(a->tx_stream[Id] + a->tx_pos[Id] + 4),
102#endif
103 data_ptr,
104 (word)to_write);
105 length -= to_write;
106 written += to_write;
107 data_ptr += to_write;
108 }
109 tmp[1] = (char)to_write;
110 tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) |
111 DIVA_DFIFO_READY |
112 ((!length && final) ? DIVA_DFIFO_LAST : 0);
113 if (tmp[0] & DIVA_DFIFO_LAST) {
114 tmp[2] = usr1;
115 tmp[3] = usr2;
116 }
117 a->ram_out_dw(a,
118#ifdef PLATFORM_GT_32BIT
119 ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
120#else
121 (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
122#endif
123 (dword *)&tmp[0],
124 1);
125 if (tmp[0] & DIVA_DFIFO_WRAP) {
126 a->tx_pos[Id] = 0;
127 } else {
128 a->tx_pos[Id] += DIVA_DFIFO_STEP;
129 }
130 if (!length) {
131 break;
132 }
133 }
134 return (written);
135}
136/* -------------------------------------------------------------------
137 In case of SYNCRONOUS service:
138 Does write data from stream in caller's buffer.
139 Does return amount of data written to buffer
140 Final flag is set on return if last part of structured frame
141 was received
142 return 0 if zero packet was received
143 return -1 if stream is empty
144 return -2 if read buffer does not profide sufficient space
145 to accommodate entire segment
146 max_length should be at least 68 bytes
147 ------------------------------------------------------------------- */
148int diva_istream_read(void *context,
149 int Id,
150 void *data,
151 int max_length,
152 int *final,
153 byte *usr1,
154 byte *usr2) {
155 ADAPTER *a = (ADAPTER *)context;
156 int read = 0, to_read = -1;
157 char tmp[4];
158 byte *data_ptr = (byte *)data;
159 *final = 0;
160 for (;;) {
161 a->ram_in_dw(a,
162#ifdef PLATFORM_GT_32BIT
163 ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
164#else
165 (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
166#endif
167 (dword *)&tmp[0],
168 1);
169 if (tmp[1] > max_length) {
170 if (to_read < 0)
171 return (-2); /* was not able to read */
172 break;
173 }
174 if (!(tmp[0] & DIVA_DFIFO_READY)) {
175 if (to_read < 0)
176 return (-1); /* was not able to read */
177 break;
178 }
179 to_read = min(max_length, (int)tmp[1]);
180 if (to_read) {
181 a->ram_in_buffer(a,
182#ifdef PLATFORM_GT_32BIT
183 ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4),
184#else
185 (void *)(a->rx_stream[Id] + a->rx_pos[Id] + 4),
186#endif
187 data_ptr,
188 (word)to_read);
189 max_length -= to_read;
190 read += to_read;
191 data_ptr += to_read;
192 }
193 if (tmp[0] & DIVA_DFIFO_LAST) {
194 *final = 1;
195 }
196 tmp[0] &= DIVA_DFIFO_WRAP;
197 a->ram_out_dw(a,
198#ifdef PLATFORM_GT_32BIT
199 ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
200#else
201 (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
202#endif
203 (dword *)&tmp[0],
204 1);
205 if (tmp[0] & DIVA_DFIFO_WRAP) {
206 a->rx_pos[Id] = 0;
207 } else {
208 a->rx_pos[Id] += DIVA_DFIFO_STEP;
209 }
210 if (*final) {
211 if (usr1)
212 *usr1 = tmp[2];
213 if (usr2)
214 *usr2 = tmp[3];
215 break;
216 }
217 }
218 return (read);
219}
220/* ---------------------------------------------------------------------
221 Does check if one of streams had caused interrupt and does
222 wake up corresponding application
223 --------------------------------------------------------------------- */
224void pr_stream(ADAPTER *a) {
225}
226#endif /* } */
diff --git a/drivers/isdn/hardware/eicon/kst_ifc.h b/drivers/isdn/hardware/eicon/kst_ifc.h
deleted file mode 100644
index 894fdfda1090..000000000000
--- a/drivers/isdn/hardware/eicon/kst_ifc.h
+++ /dev/null
@@ -1,335 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Networks, 2000.
4 *
5 This source file is supplied for the use with
6 Eicon Networks range of DIVA Server Adapters.
7 *
8 Eicon File Revision : 1.9
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, or (at your option)
13 any later version.
14 *
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the 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 */
25#ifndef __DIVA_EICON_TRACE_API__
26#define __DIVA_EICON_TRACE_API__
27
28#define DIVA_TRACE_LINE_TYPE_LEN 64
29#define DIVA_TRACE_IE_LEN 64
30#define DIVA_TRACE_FAX_PRMS_LEN 128
31
32typedef struct _diva_trace_ie {
33 byte length;
34 byte data[DIVA_TRACE_IE_LEN];
35} diva_trace_ie_t;
36
37/*
38 Structure used to represent "State\\BX\\Modem" directory
39 to user.
40*/
41typedef struct _diva_trace_modem_state {
42 dword ChannelNumber;
43
44 dword Event;
45
46 dword Norm;
47
48 dword Options; /* Options received from Application */
49
50 dword TxSpeed;
51 dword RxSpeed;
52
53 dword RoundtripMsec;
54
55 dword SymbolRate;
56
57 int RxLeveldBm;
58 int EchoLeveldBm;
59
60 dword SNRdb;
61 dword MAE;
62
63 dword LocalRetrains;
64 dword RemoteRetrains;
65 dword LocalResyncs;
66 dword RemoteResyncs;
67
68 dword DiscReason;
69
70} diva_trace_modem_state_t;
71
72/*
73 Representation of "State\\BX\\FAX" directory
74*/
75typedef struct _diva_trace_fax_state {
76 dword ChannelNumber;
77 dword Event;
78 dword Page_Counter;
79 dword Features;
80 char Station_ID[DIVA_TRACE_FAX_PRMS_LEN];
81 char Subaddress[DIVA_TRACE_FAX_PRMS_LEN];
82 char Password[DIVA_TRACE_FAX_PRMS_LEN];
83 dword Speed;
84 dword Resolution;
85 dword Paper_Width;
86 dword Paper_Length;
87 dword Scanline_Time;
88 dword Disc_Reason;
89 dword dummy;
90} diva_trace_fax_state_t;
91
92/*
93 Structure used to represent Interface State in the abstract
94 and interface/D-channel protocol independent form.
95*/
96typedef struct _diva_trace_interface_state {
97 char Layer1[DIVA_TRACE_LINE_TYPE_LEN];
98 char Layer2[DIVA_TRACE_LINE_TYPE_LEN];
99} diva_trace_interface_state_t;
100
101typedef struct _diva_incoming_call_statistics {
102 dword Calls;
103 dword Connected;
104 dword User_Busy;
105 dword Call_Rejected;
106 dword Wrong_Number;
107 dword Incompatible_Dst;
108 dword Out_of_Order;
109 dword Ignored;
110} diva_incoming_call_statistics_t;
111
112typedef struct _diva_outgoing_call_statistics {
113 dword Calls;
114 dword Connected;
115 dword User_Busy;
116 dword No_Answer;
117 dword Wrong_Number;
118 dword Call_Rejected;
119 dword Other_Failures;
120} diva_outgoing_call_statistics_t;
121
122typedef struct _diva_modem_call_statistics {
123 dword Disc_Normal;
124 dword Disc_Unspecified;
125 dword Disc_Busy_Tone;
126 dword Disc_Congestion;
127 dword Disc_Carr_Wait;
128 dword Disc_Trn_Timeout;
129 dword Disc_Incompat;
130 dword Disc_Frame_Rej;
131 dword Disc_V42bis;
132} diva_modem_call_statistics_t;
133
134typedef struct _diva_fax_call_statistics {
135 dword Disc_Normal;
136 dword Disc_Not_Ident;
137 dword Disc_No_Response;
138 dword Disc_Retries;
139 dword Disc_Unexp_Msg;
140 dword Disc_No_Polling;
141 dword Disc_Training;
142 dword Disc_Unexpected;
143 dword Disc_Application;
144 dword Disc_Incompat;
145 dword Disc_No_Command;
146 dword Disc_Long_Msg;
147 dword Disc_Supervisor;
148 dword Disc_SUB_SEP_PWD;
149 dword Disc_Invalid_Msg;
150 dword Disc_Page_Coding;
151 dword Disc_App_Timeout;
152 dword Disc_Unspecified;
153} diva_fax_call_statistics_t;
154
155typedef struct _diva_prot_statistics {
156 dword X_Frames;
157 dword X_Bytes;
158 dword X_Errors;
159 dword R_Frames;
160 dword R_Bytes;
161 dword R_Errors;
162} diva_prot_statistics_t;
163
164typedef struct _diva_ifc_statistics {
165 diva_incoming_call_statistics_t inc;
166 diva_outgoing_call_statistics_t outg;
167 diva_modem_call_statistics_t mdm;
168 diva_fax_call_statistics_t fax;
169 diva_prot_statistics_t b1;
170 diva_prot_statistics_t b2;
171 diva_prot_statistics_t d1;
172 diva_prot_statistics_t d2;
173} diva_ifc_statistics_t;
174
175/*
176 Structure used to represent "State\\BX" directory
177 to user.
178*/
179typedef struct _diva_trace_line_state {
180 dword ChannelNumber;
181
182 char Line[DIVA_TRACE_LINE_TYPE_LEN];
183
184 char Framing[DIVA_TRACE_LINE_TYPE_LEN];
185
186 char Layer2[DIVA_TRACE_LINE_TYPE_LEN];
187 char Layer3[DIVA_TRACE_LINE_TYPE_LEN];
188
189 char RemoteAddress[DIVA_TRACE_LINE_TYPE_LEN];
190 char RemoteSubAddress[DIVA_TRACE_LINE_TYPE_LEN];
191
192 char LocalAddress[DIVA_TRACE_LINE_TYPE_LEN];
193 char LocalSubAddress[DIVA_TRACE_LINE_TYPE_LEN];
194
195 diva_trace_ie_t call_BC;
196 diva_trace_ie_t call_HLC;
197 diva_trace_ie_t call_LLC;
198
199 dword Charges;
200
201 dword CallReference;
202
203 dword LastDisconnecCause;
204
205 char UserID[DIVA_TRACE_LINE_TYPE_LEN];
206
207 diva_trace_modem_state_t modem;
208 diva_trace_fax_state_t fax;
209
210 diva_trace_interface_state_t *pInterface;
211
212 diva_ifc_statistics_t *pInterfaceStat;
213
214} diva_trace_line_state_t;
215
216#define DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE ('l')
217#define DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE ('m')
218#define DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE ('f')
219#define DIVA_SUPER_TRACE_INTERFACE_CHANGE ('i')
220#define DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE ('s')
221#define DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE ('M')
222#define DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE ('F')
223
224struct _diva_strace_library_interface;
225typedef void (*diva_trace_channel_state_change_proc_t)(void *user_context,
226 struct _diva_strace_library_interface *hLib,
227 int Adapter,
228 diva_trace_line_state_t *channel, int notify_subject);
229typedef void (*diva_trace_channel_trace_proc_t)(void *user_context,
230 struct _diva_strace_library_interface *hLib,
231 int Adapter, void *xlog_buffer, int length);
232typedef void (*diva_trace_error_proc_t)(void *user_context,
233 struct _diva_strace_library_interface *hLib,
234 int Adapter,
235 int error, const char *file, int line);
236
237/*
238 This structure creates interface from user to library
239*/
240typedef struct _diva_trace_library_user_interface {
241 void *user_context;
242 diva_trace_channel_state_change_proc_t notify_proc;
243 diva_trace_channel_trace_proc_t trace_proc;
244 diva_trace_error_proc_t error_notify_proc;
245} diva_trace_library_user_interface_t;
246
247/*
248 Interface from Library to User
249*/
250typedef int (*DivaSTraceLibraryStart_proc_t)(void *hLib);
251typedef int (*DivaSTraceLibraryFinit_proc_t)(void *hLib);
252typedef int (*DivaSTraceMessageInput_proc_t)(void *hLib);
253typedef void* (*DivaSTraceGetHandle_proc_t)(void *hLib);
254
255/*
256 Turn Audio Tap trace on/off
257 Channel should be in the range 1 ... Number of Channels
258*/
259typedef int (*DivaSTraceSetAudioTap_proc_t)(void *hLib, int Channel, int on);
260
261/*
262 Turn B-channel trace on/off
263 Channel should be in the range 1 ... Number of Channels
264*/
265typedef int (*DivaSTraceSetBChannel_proc_t)(void *hLib, int Channel, int on);
266
267/*
268 Turn D-channel (Layer1/Layer2/Layer3) trace on/off
269 Layer1 - All D-channel frames received/sent over the interface
270 inclusive Layer 2 headers, Layer 2 frames and TEI management frames
271 Layer2 - Events from LAPD protocol instance with SAPI of signalling protocol
272 Layer3 - All D-channel frames addressed to assigned to the card TEI and
273 SAPI of signalling protocol, and signalling protocol events.
274*/
275typedef int (*DivaSTraceSetDChannel_proc_t)(void *hLib, int on);
276
277/*
278 Get overall card statistics
279*/
280typedef int (*DivaSTraceGetOutgoingCallStatistics_proc_t)(void *hLib);
281typedef int (*DivaSTraceGetIncomingCallStatistics_proc_t)(void *hLib);
282typedef int (*DivaSTraceGetModemStatistics_proc_t)(void *hLib);
283typedef int (*DivaSTraceGetFaxStatistics_proc_t)(void *hLib);
284typedef int (*DivaSTraceGetBLayer1Statistics_proc_t)(void *hLib);
285typedef int (*DivaSTraceGetBLayer2Statistics_proc_t)(void *hLib);
286typedef int (*DivaSTraceGetDLayer1Statistics_proc_t)(void *hLib);
287typedef int (*DivaSTraceGetDLayer2Statistics_proc_t)(void *hLib);
288
289/*
290 Call control
291*/
292typedef int (*DivaSTraceClearCall_proc_t)(void *hLib, int Channel);
293
294typedef struct _diva_strace_library_interface {
295 void *hLib;
296 DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStart;
297 DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStop;
298 DivaSTraceLibraryFinit_proc_t DivaSTraceLibraryFinit;
299 DivaSTraceMessageInput_proc_t DivaSTraceMessageInput;
300 DivaSTraceGetHandle_proc_t DivaSTraceGetHandle;
301 DivaSTraceSetAudioTap_proc_t DivaSTraceSetAudioTap;
302 DivaSTraceSetBChannel_proc_t DivaSTraceSetBChannel;
303 DivaSTraceSetDChannel_proc_t DivaSTraceSetDChannel;
304 DivaSTraceSetDChannel_proc_t DivaSTraceSetInfo;
305 DivaSTraceGetOutgoingCallStatistics_proc_t \
306 DivaSTraceGetOutgoingCallStatistics;
307 DivaSTraceGetIncomingCallStatistics_proc_t \
308 DivaSTraceGetIncomingCallStatistics;
309 DivaSTraceGetModemStatistics_proc_t \
310 DivaSTraceGetModemStatistics;
311 DivaSTraceGetFaxStatistics_proc_t \
312 DivaSTraceGetFaxStatistics;
313 DivaSTraceGetBLayer1Statistics_proc_t \
314 DivaSTraceGetBLayer1Statistics;
315 DivaSTraceGetBLayer2Statistics_proc_t \
316 DivaSTraceGetBLayer2Statistics;
317 DivaSTraceGetDLayer1Statistics_proc_t \
318 DivaSTraceGetDLayer1Statistics;
319 DivaSTraceGetDLayer2Statistics_proc_t \
320 DivaSTraceGetDLayer2Statistics;
321 DivaSTraceClearCall_proc_t DivaSTraceClearCall;
322} diva_strace_library_interface_t;
323
324/*
325 Create and return Library interface
326*/
327diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter,
328 const diva_trace_library_user_interface_t *user_proc,
329 byte *pmem);
330dword DivaSTraceGetMemotyRequirement(int channels);
331
332#define DIVA_MAX_ADAPTERS 64
333#define DIVA_MAX_LINES 32
334
335#endif
diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c
deleted file mode 100644
index 2ee789f95867..000000000000
--- a/drivers/isdn/hardware/eicon/maintidi.c
+++ /dev/null
@@ -1,2194 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Networks, 2000.
4 *
5 This source file is supplied for the use with
6 Eicon Networks range of DIVA Server Adapters.
7 *
8 Eicon File Revision : 1.9
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, or (at your option)
13 any later version.
14 *
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the 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 */
25#include "platform.h"
26#include "kst_ifc.h"
27#include "di_defs.h"
28#include "maintidi.h"
29#include "pc.h"
30#include "man_defs.h"
31
32
33extern void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);
34
35#define MODEM_PARSE_ENTRIES 16 /* amount of variables of interest */
36#define FAX_PARSE_ENTRIES 12 /* amount of variables of interest */
37#define LINE_PARSE_ENTRIES 15 /* amount of variables of interest */
38#define STAT_PARSE_ENTRIES 70 /* amount of variables of interest */
39
40/*
41 LOCAL FUNCTIONS
42*/
43static int DivaSTraceLibraryStart(void *hLib);
44static int DivaSTraceLibraryStop(void *hLib);
45static int SuperTraceLibraryFinit(void *hLib);
46static void *SuperTraceGetHandle(void *hLib);
47static int SuperTraceMessageInput(void *hLib);
48static int SuperTraceSetAudioTap(void *hLib, int Channel, int on);
49static int SuperTraceSetBChannel(void *hLib, int Channel, int on);
50static int SuperTraceSetDChannel(void *hLib, int on);
51static int SuperTraceSetInfo(void *hLib, int on);
52static int SuperTraceClearCall(void *hLib, int Channel);
53static int SuperTraceGetOutgoingCallStatistics(void *hLib);
54static int SuperTraceGetIncomingCallStatistics(void *hLib);
55static int SuperTraceGetModemStatistics(void *hLib);
56static int SuperTraceGetFaxStatistics(void *hLib);
57static int SuperTraceGetBLayer1Statistics(void *hLib);
58static int SuperTraceGetBLayer2Statistics(void *hLib);
59static int SuperTraceGetDLayer1Statistics(void *hLib);
60static int SuperTraceGetDLayer2Statistics(void *hLib);
61
62/*
63 LOCAL FUNCTIONS
64*/
65static int ScheduleNextTraceRequest(diva_strace_context_t *pLib);
66static int process_idi_event(diva_strace_context_t *pLib,
67 diva_man_var_header_t *pVar);
68static int process_idi_info(diva_strace_context_t *pLib,
69 diva_man_var_header_t *pVar);
70static int diva_modem_event(diva_strace_context_t *pLib, int Channel);
71static int diva_fax_event(diva_strace_context_t *pLib, int Channel);
72static int diva_line_event(diva_strace_context_t *pLib, int Channel);
73static int diva_modem_info(diva_strace_context_t *pLib,
74 int Channel,
75 diva_man_var_header_t *pVar);
76static int diva_fax_info(diva_strace_context_t *pLib,
77 int Channel,
78 diva_man_var_header_t *pVar);
79static int diva_line_info(diva_strace_context_t *pLib,
80 int Channel,
81 diva_man_var_header_t *pVar);
82static int diva_ifc_statistics(diva_strace_context_t *pLib,
83 diva_man_var_header_t *pVar);
84static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar);
85static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
86 const char *name);
87static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var);
88static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var);
89static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var);
90static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var);
91static int diva_strace_read_ie(diva_man_var_header_t *pVar,
92 diva_trace_ie_t *var);
93static void diva_create_parse_table(diva_strace_context_t *pLib);
94static void diva_trace_error(diva_strace_context_t *pLib,
95 int error, const char *file, int line);
96static void diva_trace_notify_user(diva_strace_context_t *pLib,
97 int Channel,
98 int notify_subject);
99static int diva_trace_read_variable(diva_man_var_header_t *pVar,
100 void *variable);
101
102/*
103 Initialize the library and return context
104 of the created trace object that will represent
105 the IDI adapter.
106 Return 0 on error.
107*/
108diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter,
109 const diva_trace_library_user_interface_t *user_proc,
110 byte *pmem) {
111 diva_strace_context_t *pLib = (diva_strace_context_t *)pmem;
112 int i;
113
114 if (!pLib) {
115 return NULL;
116 }
117
118 pmem += sizeof(*pLib);
119 memset(pLib, 0x00, sizeof(*pLib));
120
121 pLib->Adapter = Adapter;
122
123 /*
124 Set up Library Interface
125 */
126 pLib->instance.hLib = pLib;
127 pLib->instance.DivaSTraceLibraryStart = DivaSTraceLibraryStart;
128 pLib->instance.DivaSTraceLibraryStop = DivaSTraceLibraryStop;
129 pLib->instance.DivaSTraceLibraryFinit = SuperTraceLibraryFinit;
130 pLib->instance.DivaSTraceMessageInput = SuperTraceMessageInput;
131 pLib->instance.DivaSTraceGetHandle = SuperTraceGetHandle;
132 pLib->instance.DivaSTraceSetAudioTap = SuperTraceSetAudioTap;
133 pLib->instance.DivaSTraceSetBChannel = SuperTraceSetBChannel;
134 pLib->instance.DivaSTraceSetDChannel = SuperTraceSetDChannel;
135 pLib->instance.DivaSTraceSetInfo = SuperTraceSetInfo;
136 pLib->instance.DivaSTraceGetOutgoingCallStatistics = \
137 SuperTraceGetOutgoingCallStatistics;
138 pLib->instance.DivaSTraceGetIncomingCallStatistics = \
139 SuperTraceGetIncomingCallStatistics;
140 pLib->instance.DivaSTraceGetModemStatistics = \
141 SuperTraceGetModemStatistics;
142 pLib->instance.DivaSTraceGetFaxStatistics = \
143 SuperTraceGetFaxStatistics;
144 pLib->instance.DivaSTraceGetBLayer1Statistics = \
145 SuperTraceGetBLayer1Statistics;
146 pLib->instance.DivaSTraceGetBLayer2Statistics = \
147 SuperTraceGetBLayer2Statistics;
148 pLib->instance.DivaSTraceGetDLayer1Statistics = \
149 SuperTraceGetDLayer1Statistics;
150 pLib->instance.DivaSTraceGetDLayer2Statistics = \
151 SuperTraceGetDLayer2Statistics;
152 pLib->instance.DivaSTraceClearCall = SuperTraceClearCall;
153
154
155 if (user_proc) {
156 pLib->user_proc_table.user_context = user_proc->user_context;
157 pLib->user_proc_table.notify_proc = user_proc->notify_proc;
158 pLib->user_proc_table.trace_proc = user_proc->trace_proc;
159 pLib->user_proc_table.error_notify_proc = user_proc->error_notify_proc;
160 }
161
162 if (!(pLib->hAdapter = SuperTraceOpenAdapter(Adapter))) {
163 diva_mnt_internal_dprintf(0, DLI_ERR, "Can not open XDI adapter");
164 return NULL;
165 }
166 pLib->Channels = SuperTraceGetNumberOfChannels(pLib->hAdapter);
167
168 /*
169 Calculate amount of parte table entites necessary to translate
170 information from all events of onterest
171 */
172 pLib->parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
173 STAT_PARSE_ENTRIES + \
174 LINE_PARSE_ENTRIES + 1) * pLib->Channels;
175 pLib->parse_table = (diva_strace_path2action_t *)pmem;
176
177 for (i = 0; i < 30; i++) {
178 pLib->lines[i].pInterface = &pLib->Interface;
179 pLib->lines[i].pInterfaceStat = &pLib->InterfaceStat;
180 }
181
182 pLib->e.R = &pLib->RData;
183
184 pLib->req_busy = 1;
185 pLib->rc_ok = ASSIGN_OK;
186
187 diva_create_parse_table(pLib);
188
189 return ((diva_strace_library_interface_t *)pLib);
190}
191
192static int DivaSTraceLibraryStart(void *hLib) {
193 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
194
195 return (SuperTraceASSIGN(pLib->hAdapter, pLib->buffer));
196}
197
198/*
199 Return (-1) on error
200 Return (0) if was initiated or pending
201 Return (1) if removal is complete
202*/
203static int DivaSTraceLibraryStop(void *hLib) {
204 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
205
206 if (!pLib->e.Id) { /* Was never started/assigned */
207 return (1);
208 }
209
210 switch (pLib->removal_state) {
211 case 0:
212 pLib->removal_state = 1;
213 ScheduleNextTraceRequest(pLib);
214 break;
215
216 case 3:
217 return (1);
218 }
219
220 return (0);
221}
222
223static int SuperTraceLibraryFinit(void *hLib) {
224 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
225 if (pLib) {
226 if (pLib->hAdapter) {
227 SuperTraceCloseAdapter(pLib->hAdapter);
228 }
229 return (0);
230 }
231 return (-1);
232}
233
234static void *SuperTraceGetHandle(void *hLib) {
235 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
236
237 return (&pLib->e);
238}
239
240/*
241 After library handle object is gone in signaled state
242 this function should be called and will pick up incoming
243 IDI messages (return codes and indications).
244*/
245static int SuperTraceMessageInput(void *hLib) {
246 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
247 int ret = 0;
248 byte Rc, Ind;
249
250 if (pLib->e.complete == 255) {
251 /*
252 Process return code
253 */
254 pLib->req_busy = 0;
255 Rc = pLib->e.Rc;
256 pLib->e.Rc = 0;
257
258 if (pLib->removal_state == 2) {
259 pLib->removal_state = 3;
260 return (0);
261 }
262
263 if (Rc != pLib->rc_ok) {
264 int ignore = 0;
265 /*
266 Auto-detect amount of events/channels and features
267 */
268 if (pLib->general_b_ch_event == 1) {
269 pLib->general_b_ch_event = 2;
270 ignore = 1;
271 } else if (pLib->general_fax_event == 1) {
272 pLib->general_fax_event = 2;
273 ignore = 1;
274 } else if (pLib->general_mdm_event == 1) {
275 pLib->general_mdm_event = 2;
276 ignore = 1;
277 } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
278 pLib->ChannelsTraceActive = pLib->Channels;
279 ignore = 1;
280 } else if (pLib->ModemTraceActive < pLib->Channels) {
281 pLib->ModemTraceActive = pLib->Channels;
282 ignore = 1;
283 } else if (pLib->FaxTraceActive < pLib->Channels) {
284 pLib->FaxTraceActive = pLib->Channels;
285 ignore = 1;
286 } else if (pLib->audio_trace_init == 2) {
287 ignore = 1;
288 pLib->audio_trace_init = 1;
289 } else if (pLib->eye_pattern_pending) {
290 pLib->eye_pattern_pending = 0;
291 ignore = 1;
292 } else if (pLib->audio_tap_pending) {
293 pLib->audio_tap_pending = 0;
294 ignore = 1;
295 }
296
297 if (!ignore) {
298 return (-1); /* request failed */
299 }
300 } else {
301 if (pLib->general_b_ch_event == 1) {
302 pLib->ChannelsTraceActive = pLib->Channels;
303 pLib->general_b_ch_event = 2;
304 } else if (pLib->general_fax_event == 1) {
305 pLib->general_fax_event = 2;
306 pLib->FaxTraceActive = pLib->Channels;
307 } else if (pLib->general_mdm_event == 1) {
308 pLib->general_mdm_event = 2;
309 pLib->ModemTraceActive = pLib->Channels;
310 }
311 }
312 if (pLib->audio_trace_init == 2) {
313 pLib->audio_trace_init = 1;
314 }
315 pLib->rc_ok = 0xff; /* default OK after assign was done */
316 if ((ret = ScheduleNextTraceRequest(pLib))) {
317 return (-1);
318 }
319 } else {
320 /*
321 Process indication
322 Always 'RNR' indication if return code is pending
323 */
324 Ind = pLib->e.Ind;
325 pLib->e.Ind = 0;
326 if (pLib->removal_state) {
327 pLib->e.RNum = 0;
328 pLib->e.RNR = 2;
329 } else if (pLib->req_busy) {
330 pLib->e.RNum = 0;
331 pLib->e.RNR = 1;
332 } else {
333 if (pLib->e.complete != 0x02) {
334 /*
335 Look-ahead call, set up buffers
336 */
337 pLib->e.RNum = 1;
338 pLib->e.R->P = (byte *)&pLib->buffer[0];
339 pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
340
341 } else {
342 /*
343 Indication reception complete, process it now
344 */
345 byte *p = (byte *)&pLib->buffer[0];
346 pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
347
348 switch (Ind) {
349 case MAN_COMBI_IND: {
350 int total_length = pLib->e.R->PLength;
351 word this_ind_length;
352
353 while (total_length > 3 && *p) {
354 Ind = *p++;
355 this_ind_length = (word)p[0] | ((word)p[1] << 8);
356 p += 2;
357
358 switch (Ind) {
359 case MAN_INFO_IND:
360 if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
361 return (-1);
362 }
363 break;
364 case MAN_EVENT_IND:
365 if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
366 return (-1);
367 }
368 break;
369 case MAN_TRACE_IND:
370 if (pLib->trace_on == 1) {
371 /*
372 Ignore first trace event that is result of
373 EVENT_ON operation
374 */
375 pLib->trace_on++;
376 } else {
377 /*
378 Delivery XLOG buffer to application
379 */
380 if (pLib->user_proc_table.trace_proc) {
381 (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
382 &pLib->instance, pLib->Adapter,
383 p, this_ind_length);
384 }
385 }
386 break;
387 default:
388 diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
389 }
390 p += (this_ind_length + 1);
391 total_length -= (4 + this_ind_length);
392 }
393 } break;
394 case MAN_INFO_IND:
395 if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
396 return (-1);
397 }
398 break;
399 case MAN_EVENT_IND:
400 if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
401 return (-1);
402 }
403 break;
404 case MAN_TRACE_IND:
405 if (pLib->trace_on == 1) {
406 /*
407 Ignore first trace event that is result of
408 EVENT_ON operation
409 */
410 pLib->trace_on++;
411 } else {
412 /*
413 Delivery XLOG buffer to application
414 */
415 if (pLib->user_proc_table.trace_proc) {
416 (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
417 &pLib->instance, pLib->Adapter,
418 p, pLib->e.R->PLength);
419 }
420 }
421 break;
422 default:
423 diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
424 }
425 }
426 }
427 }
428
429 if ((ret = ScheduleNextTraceRequest(pLib))) {
430 return (-1);
431 }
432
433 return (ret);
434}
435
436/*
437 Internal state machine responsible for scheduling of requests
438*/
439static int ScheduleNextTraceRequest(diva_strace_context_t *pLib) {
440 char name[64];
441 int ret = 0;
442 int i;
443
444 if (pLib->req_busy) {
445 return (0);
446 }
447
448 if (pLib->removal_state == 1) {
449 if (SuperTraceREMOVE(pLib->hAdapter)) {
450 pLib->removal_state = 3;
451 } else {
452 pLib->req_busy = 1;
453 pLib->removal_state = 2;
454 }
455 return (0);
456 }
457
458 if (pLib->removal_state) {
459 return (0);
460 }
461
462 if (!pLib->general_b_ch_event) {
463 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\B Event", pLib->buffer))) {
464 return (-1);
465 }
466 pLib->general_b_ch_event = 1;
467 pLib->req_busy = 1;
468 return (0);
469 }
470
471 if (!pLib->general_fax_event) {
472 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\FAX Event", pLib->buffer))) {
473 return (-1);
474 }
475 pLib->general_fax_event = 1;
476 pLib->req_busy = 1;
477 return (0);
478 }
479
480 if (!pLib->general_mdm_event) {
481 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\Modem Event", pLib->buffer))) {
482 return (-1);
483 }
484 pLib->general_mdm_event = 1;
485 pLib->req_busy = 1;
486 return (0);
487 }
488
489 if (pLib->ChannelsTraceActive < pLib->Channels) {
490 pLib->ChannelsTraceActive++;
491 sprintf(name, "State\\B%d\\Line", pLib->ChannelsTraceActive);
492 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
493 pLib->ChannelsTraceActive--;
494 return (-1);
495 }
496 pLib->req_busy = 1;
497 return (0);
498 }
499
500 if (pLib->ModemTraceActive < pLib->Channels) {
501 pLib->ModemTraceActive++;
502 sprintf(name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive);
503 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
504 pLib->ModemTraceActive--;
505 return (-1);
506 }
507 pLib->req_busy = 1;
508 return (0);
509 }
510
511 if (pLib->FaxTraceActive < pLib->Channels) {
512 pLib->FaxTraceActive++;
513 sprintf(name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive);
514 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
515 pLib->FaxTraceActive--;
516 return (-1);
517 }
518 pLib->req_busy = 1;
519 return (0);
520 }
521
522 if (!pLib->trace_mask_init) {
523 word tmp = 0x0000;
524 if (SuperTraceWriteVar(pLib->hAdapter,
525 pLib->buffer,
526 "Trace\\Event Enable",
527 &tmp,
528 0x87, /* MI_BITFLD */
529 sizeof(tmp))) {
530 return (-1);
531 }
532 pLib->trace_mask_init = 1;
533 pLib->req_busy = 1;
534 return (0);
535 }
536
537 if (!pLib->audio_trace_init) {
538 dword tmp = 0x00000000;
539 if (SuperTraceWriteVar(pLib->hAdapter,
540 pLib->buffer,
541 "Trace\\AudioCh# Enable",
542 &tmp,
543 0x87, /* MI_BITFLD */
544 sizeof(tmp))) {
545 return (-1);
546 }
547 pLib->audio_trace_init = 2;
548 pLib->req_busy = 1;
549 return (0);
550 }
551
552 if (!pLib->bchannel_init) {
553 dword tmp = 0x00000000;
554 if (SuperTraceWriteVar(pLib->hAdapter,
555 pLib->buffer,
556 "Trace\\B-Ch# Enable",
557 &tmp,
558 0x87, /* MI_BITFLD */
559 sizeof(tmp))) {
560 return (-1);
561 }
562 pLib->bchannel_init = 1;
563 pLib->req_busy = 1;
564 return (0);
565 }
566
567 if (!pLib->trace_length_init) {
568 word tmp = 30;
569 if (SuperTraceWriteVar(pLib->hAdapter,
570 pLib->buffer,
571 "Trace\\Max Log Length",
572 &tmp,
573 0x82, /* MI_UINT */
574 sizeof(tmp))) {
575 return (-1);
576 }
577 pLib->trace_length_init = 1;
578 pLib->req_busy = 1;
579 return (0);
580 }
581
582 if (!pLib->trace_on) {
583 if (SuperTraceTraceOnRequest(pLib->hAdapter,
584 "Trace\\Log Buffer",
585 pLib->buffer)) {
586 return (-1);
587 }
588 pLib->trace_on = 1;
589 pLib->req_busy = 1;
590 return (0);
591 }
592
593 if (pLib->trace_event_mask != pLib->current_trace_event_mask) {
594 if (SuperTraceWriteVar(pLib->hAdapter,
595 pLib->buffer,
596 "Trace\\Event Enable",
597 &pLib->trace_event_mask,
598 0x87, /* MI_BITFLD */
599 sizeof(pLib->trace_event_mask))) {
600 return (-1);
601 }
602 pLib->current_trace_event_mask = pLib->trace_event_mask;
603 pLib->req_busy = 1;
604 return (0);
605 }
606
607 if ((pLib->audio_tap_pending >= 0) && (pLib->audio_tap_mask != pLib->current_audio_tap_mask)) {
608 if (SuperTraceWriteVar(pLib->hAdapter,
609 pLib->buffer,
610 "Trace\\AudioCh# Enable",
611 &pLib->audio_tap_mask,
612 0x87, /* MI_BITFLD */
613 sizeof(pLib->audio_tap_mask))) {
614 return (-1);
615 }
616 pLib->current_audio_tap_mask = pLib->audio_tap_mask;
617 pLib->audio_tap_pending = 1;
618 pLib->req_busy = 1;
619 return (0);
620 }
621
622 if ((pLib->eye_pattern_pending >= 0) && (pLib->audio_tap_mask != pLib->current_eye_pattern_mask)) {
623 if (SuperTraceWriteVar(pLib->hAdapter,
624 pLib->buffer,
625 "Trace\\EyeCh# Enable",
626 &pLib->audio_tap_mask,
627 0x87, /* MI_BITFLD */
628 sizeof(pLib->audio_tap_mask))) {
629 return (-1);
630 }
631 pLib->current_eye_pattern_mask = pLib->audio_tap_mask;
632 pLib->eye_pattern_pending = 1;
633 pLib->req_busy = 1;
634 return (0);
635 }
636
637 if (pLib->bchannel_trace_mask != pLib->current_bchannel_trace_mask) {
638 if (SuperTraceWriteVar(pLib->hAdapter,
639 pLib->buffer,
640 "Trace\\B-Ch# Enable",
641 &pLib->bchannel_trace_mask,
642 0x87, /* MI_BITFLD */
643 sizeof(pLib->bchannel_trace_mask))) {
644 return (-1);
645 }
646 pLib->current_bchannel_trace_mask = pLib->bchannel_trace_mask;
647 pLib->req_busy = 1;
648 return (0);
649 }
650
651 if (!pLib->trace_events_down) {
652 if (SuperTraceTraceOnRequest(pLib->hAdapter,
653 "Events Down",
654 pLib->buffer)) {
655 return (-1);
656 }
657 pLib->trace_events_down = 1;
658 pLib->req_busy = 1;
659 return (0);
660 }
661
662 if (!pLib->l1_trace) {
663 if (SuperTraceTraceOnRequest(pLib->hAdapter,
664 "State\\Layer1",
665 pLib->buffer)) {
666 return (-1);
667 }
668 pLib->l1_trace = 1;
669 pLib->req_busy = 1;
670 return (0);
671 }
672
673 if (!pLib->l2_trace) {
674 if (SuperTraceTraceOnRequest(pLib->hAdapter,
675 "State\\Layer2 No1",
676 pLib->buffer)) {
677 return (-1);
678 }
679 pLib->l2_trace = 1;
680 pLib->req_busy = 1;
681 return (0);
682 }
683
684 for (i = 0; i < 30; i++) {
685 if (pLib->pending_line_status & (1L << i)) {
686 sprintf(name, "State\\B%d", i + 1);
687 if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
688 return (-1);
689 }
690 pLib->pending_line_status &= ~(1L << i);
691 pLib->req_busy = 1;
692 return (0);
693 }
694 if (pLib->pending_modem_status & (1L << i)) {
695 sprintf(name, "State\\B%d\\Modem", i + 1);
696 if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
697 return (-1);
698 }
699 pLib->pending_modem_status &= ~(1L << i);
700 pLib->req_busy = 1;
701 return (0);
702 }
703 if (pLib->pending_fax_status & (1L << i)) {
704 sprintf(name, "State\\B%d\\FAX", i + 1);
705 if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
706 return (-1);
707 }
708 pLib->pending_fax_status &= ~(1L << i);
709 pLib->req_busy = 1;
710 return (0);
711 }
712 if (pLib->clear_call_command & (1L << i)) {
713 sprintf(name, "State\\B%d\\Clear Call", i + 1);
714 if (SuperTraceExecuteRequest(pLib->hAdapter, name, pLib->buffer)) {
715 return (-1);
716 }
717 pLib->clear_call_command &= ~(1L << i);
718 pLib->req_busy = 1;
719 return (0);
720 }
721 }
722
723 if (pLib->outgoing_ifc_stats) {
724 if (SuperTraceReadRequest(pLib->hAdapter,
725 "Statistics\\Outgoing Calls",
726 pLib->buffer)) {
727 return (-1);
728 }
729 pLib->outgoing_ifc_stats = 0;
730 pLib->req_busy = 1;
731 return (0);
732 }
733
734 if (pLib->incoming_ifc_stats) {
735 if (SuperTraceReadRequest(pLib->hAdapter,
736 "Statistics\\Incoming Calls",
737 pLib->buffer)) {
738 return (-1);
739 }
740 pLib->incoming_ifc_stats = 0;
741 pLib->req_busy = 1;
742 return (0);
743 }
744
745 if (pLib->modem_ifc_stats) {
746 if (SuperTraceReadRequest(pLib->hAdapter,
747 "Statistics\\Modem",
748 pLib->buffer)) {
749 return (-1);
750 }
751 pLib->modem_ifc_stats = 0;
752 pLib->req_busy = 1;
753 return (0);
754 }
755
756 if (pLib->fax_ifc_stats) {
757 if (SuperTraceReadRequest(pLib->hAdapter,
758 "Statistics\\FAX",
759 pLib->buffer)) {
760 return (-1);
761 }
762 pLib->fax_ifc_stats = 0;
763 pLib->req_busy = 1;
764 return (0);
765 }
766
767 if (pLib->b1_ifc_stats) {
768 if (SuperTraceReadRequest(pLib->hAdapter,
769 "Statistics\\B-Layer1",
770 pLib->buffer)) {
771 return (-1);
772 }
773 pLib->b1_ifc_stats = 0;
774 pLib->req_busy = 1;
775 return (0);
776 }
777
778 if (pLib->b2_ifc_stats) {
779 if (SuperTraceReadRequest(pLib->hAdapter,
780 "Statistics\\B-Layer2",
781 pLib->buffer)) {
782 return (-1);
783 }
784 pLib->b2_ifc_stats = 0;
785 pLib->req_busy = 1;
786 return (0);
787 }
788
789 if (pLib->d1_ifc_stats) {
790 if (SuperTraceReadRequest(pLib->hAdapter,
791 "Statistics\\D-Layer1",
792 pLib->buffer)) {
793 return (-1);
794 }
795 pLib->d1_ifc_stats = 0;
796 pLib->req_busy = 1;
797 return (0);
798 }
799
800 if (pLib->d2_ifc_stats) {
801 if (SuperTraceReadRequest(pLib->hAdapter,
802 "Statistics\\D-Layer2",
803 pLib->buffer)) {
804 return (-1);
805 }
806 pLib->d2_ifc_stats = 0;
807 pLib->req_busy = 1;
808 return (0);
809 }
810
811 if (!pLib->IncomingCallsCallsActive) {
812 pLib->IncomingCallsCallsActive = 1;
813 sprintf(name, "%s", "Statistics\\Incoming Calls\\Calls");
814 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
815 pLib->IncomingCallsCallsActive = 0;
816 return (-1);
817 }
818 pLib->req_busy = 1;
819 return (0);
820 }
821 if (!pLib->IncomingCallsConnectedActive) {
822 pLib->IncomingCallsConnectedActive = 1;
823 sprintf(name, "%s", "Statistics\\Incoming Calls\\Connected");
824 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
825 pLib->IncomingCallsConnectedActive = 0;
826 return (-1);
827 }
828 pLib->req_busy = 1;
829 return (0);
830 }
831 if (!pLib->OutgoingCallsCallsActive) {
832 pLib->OutgoingCallsCallsActive = 1;
833 sprintf(name, "%s", "Statistics\\Outgoing Calls\\Calls");
834 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
835 pLib->OutgoingCallsCallsActive = 0;
836 return (-1);
837 }
838 pLib->req_busy = 1;
839 return (0);
840 }
841 if (!pLib->OutgoingCallsConnectedActive) {
842 pLib->OutgoingCallsConnectedActive = 1;
843 sprintf(name, "%s", "Statistics\\Outgoing Calls\\Connected");
844 if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
845 pLib->OutgoingCallsConnectedActive = 0;
846 return (-1);
847 }
848 pLib->req_busy = 1;
849 return (0);
850 }
851
852 return (0);
853}
854
855static int process_idi_event(diva_strace_context_t *pLib,
856 diva_man_var_header_t *pVar) {
857 const char *path = (char *)&pVar->path_length + 1;
858 char name[64];
859 int i;
860
861 if (!strncmp("State\\B Event", path, pVar->path_length)) {
862 dword ch_id;
863 if (!diva_trace_read_variable(pVar, &ch_id)) {
864 if (!pLib->line_init_event && !pLib->pending_line_status) {
865 for (i = 1; i <= pLib->Channels; i++) {
866 diva_line_event(pLib, i);
867 }
868 return (0);
869 } else if (ch_id && ch_id <= pLib->Channels) {
870 return (diva_line_event(pLib, (int)ch_id));
871 }
872 return (0);
873 }
874 return (-1);
875 }
876
877 if (!strncmp("State\\FAX Event", path, pVar->path_length)) {
878 dword ch_id;
879 if (!diva_trace_read_variable(pVar, &ch_id)) {
880 if (!pLib->pending_fax_status && !pLib->fax_init_event) {
881 for (i = 1; i <= pLib->Channels; i++) {
882 diva_fax_event(pLib, i);
883 }
884 return (0);
885 } else if (ch_id && ch_id <= pLib->Channels) {
886 return (diva_fax_event(pLib, (int)ch_id));
887 }
888 return (0);
889 }
890 return (-1);
891 }
892
893 if (!strncmp("State\\Modem Event", path, pVar->path_length)) {
894 dword ch_id;
895 if (!diva_trace_read_variable(pVar, &ch_id)) {
896 if (!pLib->pending_modem_status && !pLib->modem_init_event) {
897 for (i = 1; i <= pLib->Channels; i++) {
898 diva_modem_event(pLib, i);
899 }
900 return (0);
901 } else if (ch_id && ch_id <= pLib->Channels) {
902 return (diva_modem_event(pLib, (int)ch_id));
903 }
904 return (0);
905 }
906 return (-1);
907 }
908
909 /*
910 First look for Line Event
911 */
912 for (i = 1; i <= pLib->Channels; i++) {
913 sprintf(name, "State\\B%d\\Line", i);
914 if (find_var(pVar, name)) {
915 return (diva_line_event(pLib, i));
916 }
917 }
918
919 /*
920 Look for Moden Progress Event
921 */
922 for (i = 1; i <= pLib->Channels; i++) {
923 sprintf(name, "State\\B%d\\Modem\\Event", i);
924 if (find_var(pVar, name)) {
925 return (diva_modem_event(pLib, i));
926 }
927 }
928
929 /*
930 Look for Fax Event
931 */
932 for (i = 1; i <= pLib->Channels; i++) {
933 sprintf(name, "State\\B%d\\FAX\\Event", i);
934 if (find_var(pVar, name)) {
935 return (diva_fax_event(pLib, i));
936 }
937 }
938
939 /*
940 Notification about loss of events
941 */
942 if (!strncmp("Events Down", path, pVar->path_length)) {
943 if (pLib->trace_events_down == 1) {
944 pLib->trace_events_down = 2;
945 } else {
946 diva_trace_error(pLib, 1, "Events Down", 0);
947 }
948 return (0);
949 }
950
951 if (!strncmp("State\\Layer1", path, pVar->path_length)) {
952 diva_strace_read_asz(pVar, &pLib->lines[0].pInterface->Layer1[0]);
953 if (pLib->l1_trace == 1) {
954 pLib->l1_trace = 2;
955 } else {
956 diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
957 }
958 return (0);
959 }
960 if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
961 char *tmp = &pLib->lines[0].pInterface->Layer2[0];
962 dword l2_state;
963 if (diva_strace_read_uint(pVar, &l2_state))
964 return -1;
965
966 switch (l2_state) {
967 case 0:
968 strcpy(tmp, "Idle");
969 break;
970 case 1:
971 strcpy(tmp, "Layer2 UP");
972 break;
973 case 2:
974 strcpy(tmp, "Layer2 Disconnecting");
975 break;
976 case 3:
977 strcpy(tmp, "Layer2 Connecting");
978 break;
979 case 4:
980 strcpy(tmp, "SPID Initializing");
981 break;
982 case 5:
983 strcpy(tmp, "SPID Initialised");
984 break;
985 case 6:
986 strcpy(tmp, "Layer2 Connecting");
987 break;
988
989 case 7:
990 strcpy(tmp, "Auto SPID Stopped");
991 break;
992
993 case 8:
994 strcpy(tmp, "Auto SPID Idle");
995 break;
996
997 case 9:
998 strcpy(tmp, "Auto SPID Requested");
999 break;
1000
1001 case 10:
1002 strcpy(tmp, "Auto SPID Delivery");
1003 break;
1004
1005 case 11:
1006 strcpy(tmp, "Auto SPID Complete");
1007 break;
1008
1009 default:
1010 sprintf(tmp, "U:%d", (int)l2_state);
1011 }
1012 if (pLib->l2_trace == 1) {
1013 pLib->l2_trace = 2;
1014 } else {
1015 diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
1016 }
1017 return (0);
1018 }
1019
1020 if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) ||
1021 !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
1022 return (SuperTraceGetIncomingCallStatistics(pLib));
1023 }
1024
1025 if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) ||
1026 !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
1027 return (SuperTraceGetOutgoingCallStatistics(pLib));
1028 }
1029
1030 return (-1);
1031}
1032
1033static int diva_line_event(diva_strace_context_t *pLib, int Channel) {
1034 pLib->pending_line_status |= (1L << (Channel - 1));
1035 return (0);
1036}
1037
1038static int diva_modem_event(diva_strace_context_t *pLib, int Channel) {
1039 pLib->pending_modem_status |= (1L << (Channel - 1));
1040 return (0);
1041}
1042
1043static int diva_fax_event(diva_strace_context_t *pLib, int Channel) {
1044 pLib->pending_fax_status |= (1L << (Channel - 1));
1045 return (0);
1046}
1047
1048/*
1049 Process INFO indications that arrive from the card
1050 Uses path of first I.E. to detect the source of the
1051 infication
1052*/
1053static int process_idi_info(diva_strace_context_t *pLib,
1054 diva_man_var_header_t *pVar) {
1055 const char *path = (char *)&pVar->path_length + 1;
1056 char name[64];
1057 int i, len;
1058
1059 /*
1060 First look for Modem Status Info
1061 */
1062 for (i = pLib->Channels; i > 0; i--) {
1063 len = sprintf(name, "State\\B%d\\Modem", i);
1064 if (!strncmp(name, path, len)) {
1065 return (diva_modem_info(pLib, i, pVar));
1066 }
1067 }
1068
1069 /*
1070 Look for Fax Status Info
1071 */
1072 for (i = pLib->Channels; i > 0; i--) {
1073 len = sprintf(name, "State\\B%d\\FAX", i);
1074 if (!strncmp(name, path, len)) {
1075 return (diva_fax_info(pLib, i, pVar));
1076 }
1077 }
1078
1079 /*
1080 Look for Line Status Info
1081 */
1082 for (i = pLib->Channels; i > 0; i--) {
1083 len = sprintf(name, "State\\B%d", i);
1084 if (!strncmp(name, path, len)) {
1085 return (diva_line_info(pLib, i, pVar));
1086 }
1087 }
1088
1089 if (!diva_ifc_statistics(pLib, pVar)) {
1090 return (0);
1091 }
1092
1093 return (-1);
1094}
1095
1096/*
1097 MODEM INSTANCE STATE UPDATE
1098
1099 Update Modem Status Information and issue notification to user,
1100 that will inform about change in the state of modem instance, that is
1101 associuated with this channel
1102*/
1103static int diva_modem_info(diva_strace_context_t *pLib,
1104 int Channel,
1105 diva_man_var_header_t *pVar) {
1106 diva_man_var_header_t *cur;
1107 int i, nr = Channel - 1;
1108
1109 for (i = pLib->modem_parse_entry_first[nr];
1110 i <= pLib->modem_parse_entry_last[nr]; i++) {
1111 if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1112 if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1113 diva_trace_error(pLib, -3, __FILE__, __LINE__);
1114 return (-1);
1115 }
1116 } else {
1117 diva_trace_error(pLib, -2, __FILE__, __LINE__);
1118 return (-1);
1119 }
1120 }
1121
1122 /*
1123 We do not use first event to notify user - this is the event that is
1124 generated as result of EVENT ON operation and is used only to initialize
1125 internal variables of application
1126 */
1127 if (pLib->modem_init_event & (1L << nr)) {
1128 diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
1129 } else {
1130 pLib->modem_init_event |= (1L << nr);
1131 }
1132
1133 return (0);
1134}
1135
1136static int diva_fax_info(diva_strace_context_t *pLib,
1137 int Channel,
1138 diva_man_var_header_t *pVar) {
1139 diva_man_var_header_t *cur;
1140 int i, nr = Channel - 1;
1141
1142 for (i = pLib->fax_parse_entry_first[nr];
1143 i <= pLib->fax_parse_entry_last[nr]; i++) {
1144 if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1145 if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1146 diva_trace_error(pLib, -3, __FILE__, __LINE__);
1147 return (-1);
1148 }
1149 } else {
1150 diva_trace_error(pLib, -2, __FILE__, __LINE__);
1151 return (-1);
1152 }
1153 }
1154
1155 /*
1156 We do not use first event to notify user - this is the event that is
1157 generated as result of EVENT ON operation and is used only to initialize
1158 internal variables of application
1159 */
1160 if (pLib->fax_init_event & (1L << nr)) {
1161 diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
1162 } else {
1163 pLib->fax_init_event |= (1L << nr);
1164 }
1165
1166 return (0);
1167}
1168
1169/*
1170 LINE STATE UPDATE
1171 Update Line Status Information and issue notification to user,
1172 that will inform about change in the line state.
1173*/
1174static int diva_line_info(diva_strace_context_t *pLib,
1175 int Channel,
1176 diva_man_var_header_t *pVar) {
1177 diva_man_var_header_t *cur;
1178 int i, nr = Channel - 1;
1179
1180 for (i = pLib->line_parse_entry_first[nr];
1181 i <= pLib->line_parse_entry_last[nr]; i++) {
1182 if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1183 if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1184 diva_trace_error(pLib, -3, __FILE__, __LINE__);
1185 return (-1);
1186 }
1187 } else {
1188 diva_trace_error(pLib, -2 , __FILE__, __LINE__);
1189 return (-1);
1190 }
1191 }
1192
1193 /*
1194 We do not use first event to notify user - this is the event that is
1195 generated as result of EVENT ON operation and is used only to initialize
1196 internal variables of application
1197
1198 Exception is is if the line is "online". In this case we have to notify
1199 user about this confition.
1200 */
1201 if (pLib->line_init_event & (1L << nr)) {
1202 diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1203 } else {
1204 pLib->line_init_event |= (1L << nr);
1205 if (strcmp(&pLib->lines[nr].Line[0], "Idle")) {
1206 diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1207 }
1208 }
1209
1210 return (0);
1211}
1212
1213/*
1214 Move position to next vatianle in the chain
1215*/
1216static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar) {
1217 byte *msg = (byte *)pVar;
1218 byte *start;
1219 int msg_length;
1220
1221 if (*msg != ESC) return NULL;
1222
1223 start = msg + 2;
1224 msg_length = *(msg + 1);
1225 msg = (start + msg_length);
1226
1227 if (*msg != ESC) return NULL;
1228
1229 return ((diva_man_var_header_t *)msg);
1230}
1231
1232/*
1233 Move position to variable with given name
1234*/
1235static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
1236 const char *name) {
1237 const char *path;
1238
1239 do {
1240 path = (char *)&pVar->path_length + 1;
1241
1242 if (!strncmp(name, path, pVar->path_length)) {
1243 break;
1244 }
1245 } while ((pVar = get_next_var(pVar)));
1246
1247 return (pVar);
1248}
1249
1250static void diva_create_line_parse_table(diva_strace_context_t *pLib,
1251 int Channel) {
1252 diva_trace_line_state_t *pLine = &pLib->lines[Channel];
1253 int nr = Channel + 1;
1254
1255 if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) {
1256 diva_trace_error(pLib, -1, __FILE__, __LINE__);
1257 return;
1258 }
1259
1260 pLine->ChannelNumber = nr;
1261
1262 pLib->line_parse_entry_first[Channel] = pLib->cur_parse_entry;
1263
1264 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1265 "State\\B%d\\Framing", nr);
1266 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0];
1267
1268 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1269 "State\\B%d\\Line", nr);
1270 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0];
1271
1272 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1273 "State\\B%d\\Layer2", nr);
1274 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0];
1275
1276 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1277 "State\\B%d\\Layer3", nr);
1278 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0];
1279
1280 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1281 "State\\B%d\\Remote Address", nr);
1282 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1283 &pLine->RemoteAddress[0];
1284
1285 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1286 "State\\B%d\\Remote SubAddr", nr);
1287 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1288 &pLine->RemoteSubAddress[0];
1289
1290 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1291 "State\\B%d\\Local Address", nr);
1292 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1293 &pLine->LocalAddress[0];
1294
1295 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1296 "State\\B%d\\Local SubAddr", nr);
1297 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1298 &pLine->LocalSubAddress[0];
1299
1300 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1301 "State\\B%d\\BC", nr);
1302 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC;
1303
1304 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1305 "State\\B%d\\HLC", nr);
1306 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC;
1307
1308 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1309 "State\\B%d\\LLC", nr);
1310 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC;
1311
1312 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1313 "State\\B%d\\Charges", nr);
1314 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges;
1315
1316 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1317 "State\\B%d\\Call Reference", nr);
1318 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference;
1319
1320 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1321 "State\\B%d\\Last Disc Cause", nr);
1322 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1323 &pLine->LastDisconnecCause;
1324
1325 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1326 "State\\B%d\\User ID", nr);
1327 pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0];
1328
1329 pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1330}
1331
1332static void diva_create_fax_parse_table(diva_strace_context_t *pLib,
1333 int Channel) {
1334 diva_trace_fax_state_t *pFax = &pLib->lines[Channel].fax;
1335 int nr = Channel + 1;
1336
1337 if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) {
1338 diva_trace_error(pLib, -1, __FILE__, __LINE__);
1339 return;
1340 }
1341 pFax->ChannelNumber = nr;
1342
1343 pLib->fax_parse_entry_first[Channel] = pLib->cur_parse_entry;
1344
1345 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1346 "State\\B%d\\FAX\\Event", nr);
1347 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event;
1348
1349 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1350 "State\\B%d\\FAX\\Page Counter", nr);
1351 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter;
1352
1353 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1354 "State\\B%d\\FAX\\Features", nr);
1355 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features;
1356
1357 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1358 "State\\B%d\\FAX\\Station ID", nr);
1359 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0];
1360
1361 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1362 "State\\B%d\\FAX\\Subaddress", nr);
1363 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0];
1364
1365 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1366 "State\\B%d\\FAX\\Password", nr);
1367 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0];
1368
1369 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1370 "State\\B%d\\FAX\\Speed", nr);
1371 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed;
1372
1373 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1374 "State\\B%d\\FAX\\Resolution", nr);
1375 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution;
1376
1377 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1378 "State\\B%d\\FAX\\Paper Width", nr);
1379 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width;
1380
1381 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1382 "State\\B%d\\FAX\\Paper Length", nr);
1383 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length;
1384
1385 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1386 "State\\B%d\\FAX\\Scanline Time", nr);
1387 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time;
1388
1389 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1390 "State\\B%d\\FAX\\Disc Reason", nr);
1391 pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason;
1392
1393 pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1394}
1395
1396static void diva_create_modem_parse_table(diva_strace_context_t *pLib,
1397 int Channel) {
1398 diva_trace_modem_state_t *pModem = &pLib->lines[Channel].modem;
1399 int nr = Channel + 1;
1400
1401 if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) {
1402 diva_trace_error(pLib, -1, __FILE__, __LINE__);
1403 return;
1404 }
1405 pModem->ChannelNumber = nr;
1406
1407 pLib->modem_parse_entry_first[Channel] = pLib->cur_parse_entry;
1408
1409 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1410 "State\\B%d\\Modem\\Event", nr);
1411 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event;
1412
1413 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1414 "State\\B%d\\Modem\\Norm", nr);
1415 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm;
1416
1417 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1418 "State\\B%d\\Modem\\Options", nr);
1419 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options;
1420
1421 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1422 "State\\B%d\\Modem\\TX Speed", nr);
1423 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed;
1424
1425 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1426 "State\\B%d\\Modem\\RX Speed", nr);
1427 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed;
1428
1429 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1430 "State\\B%d\\Modem\\Roundtrip ms", nr);
1431 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec;
1432
1433 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1434 "State\\B%d\\Modem\\Symbol Rate", nr);
1435 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate;
1436
1437 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1438 "State\\B%d\\Modem\\RX Level dBm", nr);
1439 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm;
1440
1441 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1442 "State\\B%d\\Modem\\Echo Level dBm", nr);
1443 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm;
1444
1445 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1446 "State\\B%d\\Modem\\SNR dB", nr);
1447 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb;
1448
1449 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1450 "State\\B%d\\Modem\\MAE", nr);
1451 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE;
1452
1453 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1454 "State\\B%d\\Modem\\Local Retrains", nr);
1455 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains;
1456
1457 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1458 "State\\B%d\\Modem\\Remote Retrains", nr);
1459 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains;
1460
1461 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1462 "State\\B%d\\Modem\\Local Resyncs", nr);
1463 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs;
1464
1465 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1466 "State\\B%d\\Modem\\Remote Resyncs", nr);
1467 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs;
1468
1469 sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1470 "State\\B%d\\Modem\\Disc Reason", nr);
1471 pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason;
1472
1473 pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1474}
1475
1476static void diva_create_parse_table(diva_strace_context_t *pLib) {
1477 int i;
1478
1479 for (i = 0; i < pLib->Channels; i++) {
1480 diva_create_line_parse_table(pLib, i);
1481 diva_create_modem_parse_table(pLib, i);
1482 diva_create_fax_parse_table(pLib, i);
1483 }
1484
1485 pLib->statistic_parse_first = pLib->cur_parse_entry;
1486
1487 /*
1488 Outgoing Calls
1489 */
1490 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1491 "Statistics\\Outgoing Calls\\Calls");
1492 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1493 &pLib->InterfaceStat.outg.Calls;
1494
1495 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1496 "Statistics\\Outgoing Calls\\Connected");
1497 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1498 &pLib->InterfaceStat.outg.Connected;
1499
1500 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1501 "Statistics\\Outgoing Calls\\User Busy");
1502 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1503 &pLib->InterfaceStat.outg.User_Busy;
1504
1505 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1506 "Statistics\\Outgoing Calls\\No Answer");
1507 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1508 &pLib->InterfaceStat.outg.No_Answer;
1509
1510 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1511 "Statistics\\Outgoing Calls\\Wrong Number");
1512 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1513 &pLib->InterfaceStat.outg.Wrong_Number;
1514
1515 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1516 "Statistics\\Outgoing Calls\\Call Rejected");
1517 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1518 &pLib->InterfaceStat.outg.Call_Rejected;
1519
1520 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1521 "Statistics\\Outgoing Calls\\Other Failures");
1522 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1523 &pLib->InterfaceStat.outg.Other_Failures;
1524
1525 /*
1526 Incoming Calls
1527 */
1528 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1529 "Statistics\\Incoming Calls\\Calls");
1530 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1531 &pLib->InterfaceStat.inc.Calls;
1532
1533 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1534 "Statistics\\Incoming Calls\\Connected");
1535 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1536 &pLib->InterfaceStat.inc.Connected;
1537
1538 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1539 "Statistics\\Incoming Calls\\User Busy");
1540 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1541 &pLib->InterfaceStat.inc.User_Busy;
1542
1543 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1544 "Statistics\\Incoming Calls\\Call Rejected");
1545 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1546 &pLib->InterfaceStat.inc.Call_Rejected;
1547
1548 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1549 "Statistics\\Incoming Calls\\Wrong Number");
1550 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1551 &pLib->InterfaceStat.inc.Wrong_Number;
1552
1553 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1554 "Statistics\\Incoming Calls\\Incompatible Dst");
1555 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1556 &pLib->InterfaceStat.inc.Incompatible_Dst;
1557
1558 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1559 "Statistics\\Incoming Calls\\Out of Order");
1560 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1561 &pLib->InterfaceStat.inc.Out_of_Order;
1562
1563 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1564 "Statistics\\Incoming Calls\\Ignored");
1565 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1566 &pLib->InterfaceStat.inc.Ignored;
1567
1568 /*
1569 Modem Statistics
1570 */
1571 pLib->mdm_statistic_parse_first = pLib->cur_parse_entry;
1572
1573 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1574 "Statistics\\Modem\\Disc Normal");
1575 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1576 &pLib->InterfaceStat.mdm.Disc_Normal;
1577
1578 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1579 "Statistics\\Modem\\Disc Unspecified");
1580 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1581 &pLib->InterfaceStat.mdm.Disc_Unspecified;
1582
1583 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1584 "Statistics\\Modem\\Disc Busy Tone");
1585 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1586 &pLib->InterfaceStat.mdm.Disc_Busy_Tone;
1587
1588 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1589 "Statistics\\Modem\\Disc Congestion");
1590 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1591 &pLib->InterfaceStat.mdm.Disc_Congestion;
1592
1593 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1594 "Statistics\\Modem\\Disc Carr. Wait");
1595 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1596 &pLib->InterfaceStat.mdm.Disc_Carr_Wait;
1597
1598 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1599 "Statistics\\Modem\\Disc Trn Timeout");
1600 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1601 &pLib->InterfaceStat.mdm.Disc_Trn_Timeout;
1602
1603 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1604 "Statistics\\Modem\\Disc Incompat.");
1605 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1606 &pLib->InterfaceStat.mdm.Disc_Incompat;
1607
1608 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1609 "Statistics\\Modem\\Disc Frame Rej.");
1610 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1611 &pLib->InterfaceStat.mdm.Disc_Frame_Rej;
1612
1613 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1614 "Statistics\\Modem\\Disc V42bis");
1615 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1616 &pLib->InterfaceStat.mdm.Disc_V42bis;
1617
1618 pLib->mdm_statistic_parse_last = pLib->cur_parse_entry - 1;
1619
1620 /*
1621 Fax Statistics
1622 */
1623 pLib->fax_statistic_parse_first = pLib->cur_parse_entry;
1624
1625 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1626 "Statistics\\FAX\\Disc Normal");
1627 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1628 &pLib->InterfaceStat.fax.Disc_Normal;
1629
1630 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1631 "Statistics\\FAX\\Disc Not Ident.");
1632 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1633 &pLib->InterfaceStat.fax.Disc_Not_Ident;
1634
1635 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1636 "Statistics\\FAX\\Disc No Response");
1637 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1638 &pLib->InterfaceStat.fax.Disc_No_Response;
1639
1640 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1641 "Statistics\\FAX\\Disc Retries");
1642 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1643 &pLib->InterfaceStat.fax.Disc_Retries;
1644
1645 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1646 "Statistics\\FAX\\Disc Unexp. Msg.");
1647 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1648 &pLib->InterfaceStat.fax.Disc_Unexp_Msg;
1649
1650 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1651 "Statistics\\FAX\\Disc No Polling.");
1652 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1653 &pLib->InterfaceStat.fax.Disc_No_Polling;
1654
1655 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1656 "Statistics\\FAX\\Disc Training");
1657 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1658 &pLib->InterfaceStat.fax.Disc_Training;
1659
1660 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1661 "Statistics\\FAX\\Disc Unexpected");
1662 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1663 &pLib->InterfaceStat.fax.Disc_Unexpected;
1664
1665 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1666 "Statistics\\FAX\\Disc Application");
1667 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1668 &pLib->InterfaceStat.fax.Disc_Application;
1669
1670 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1671 "Statistics\\FAX\\Disc Incompat.");
1672 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1673 &pLib->InterfaceStat.fax.Disc_Incompat;
1674
1675 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1676 "Statistics\\FAX\\Disc No Command");
1677 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1678 &pLib->InterfaceStat.fax.Disc_No_Command;
1679
1680 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1681 "Statistics\\FAX\\Disc Long Msg");
1682 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1683 &pLib->InterfaceStat.fax.Disc_Long_Msg;
1684
1685 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1686 "Statistics\\FAX\\Disc Supervisor");
1687 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1688 &pLib->InterfaceStat.fax.Disc_Supervisor;
1689
1690 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1691 "Statistics\\FAX\\Disc SUB SEP PWD");
1692 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1693 &pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD;
1694
1695 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1696 "Statistics\\FAX\\Disc Invalid Msg");
1697 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1698 &pLib->InterfaceStat.fax.Disc_Invalid_Msg;
1699
1700 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1701 "Statistics\\FAX\\Disc Page Coding");
1702 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1703 &pLib->InterfaceStat.fax.Disc_Page_Coding;
1704
1705 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1706 "Statistics\\FAX\\Disc App Timeout");
1707 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1708 &pLib->InterfaceStat.fax.Disc_App_Timeout;
1709
1710 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1711 "Statistics\\FAX\\Disc Unspecified");
1712 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1713 &pLib->InterfaceStat.fax.Disc_Unspecified;
1714
1715 pLib->fax_statistic_parse_last = pLib->cur_parse_entry - 1;
1716
1717 /*
1718 B-Layer1"
1719 */
1720 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1721 "Statistics\\B-Layer1\\X-Frames");
1722 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1723 &pLib->InterfaceStat.b1.X_Frames;
1724
1725 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1726 "Statistics\\B-Layer1\\X-Bytes");
1727 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1728 &pLib->InterfaceStat.b1.X_Bytes;
1729
1730 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1731 "Statistics\\B-Layer1\\X-Errors");
1732 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1733 &pLib->InterfaceStat.b1.X_Errors;
1734
1735 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1736 "Statistics\\B-Layer1\\R-Frames");
1737 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1738 &pLib->InterfaceStat.b1.R_Frames;
1739
1740 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1741 "Statistics\\B-Layer1\\R-Bytes");
1742 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1743 &pLib->InterfaceStat.b1.R_Bytes;
1744
1745 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1746 "Statistics\\B-Layer1\\R-Errors");
1747 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1748 &pLib->InterfaceStat.b1.R_Errors;
1749
1750 /*
1751 B-Layer2
1752 */
1753 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1754 "Statistics\\B-Layer2\\X-Frames");
1755 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1756 &pLib->InterfaceStat.b2.X_Frames;
1757
1758 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1759 "Statistics\\B-Layer2\\X-Bytes");
1760 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1761 &pLib->InterfaceStat.b2.X_Bytes;
1762
1763 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1764 "Statistics\\B-Layer2\\X-Errors");
1765 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1766 &pLib->InterfaceStat.b2.X_Errors;
1767
1768 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1769 "Statistics\\B-Layer2\\R-Frames");
1770 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1771 &pLib->InterfaceStat.b2.R_Frames;
1772
1773 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1774 "Statistics\\B-Layer2\\R-Bytes");
1775 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1776 &pLib->InterfaceStat.b2.R_Bytes;
1777
1778 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1779 "Statistics\\B-Layer2\\R-Errors");
1780 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1781 &pLib->InterfaceStat.b2.R_Errors;
1782
1783 /*
1784 D-Layer1
1785 */
1786 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1787 "Statistics\\D-Layer1\\X-Frames");
1788 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1789 &pLib->InterfaceStat.d1.X_Frames;
1790
1791 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1792 "Statistics\\D-Layer1\\X-Bytes");
1793 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1794 &pLib->InterfaceStat.d1.X_Bytes;
1795
1796 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1797 "Statistics\\D-Layer1\\X-Errors");
1798 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1799 &pLib->InterfaceStat.d1.X_Errors;
1800
1801 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1802 "Statistics\\D-Layer1\\R-Frames");
1803 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1804 &pLib->InterfaceStat.d1.R_Frames;
1805
1806 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1807 "Statistics\\D-Layer1\\R-Bytes");
1808 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1809 &pLib->InterfaceStat.d1.R_Bytes;
1810
1811 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1812 "Statistics\\D-Layer1\\R-Errors");
1813 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1814 &pLib->InterfaceStat.d1.R_Errors;
1815
1816 /*
1817 D-Layer2
1818 */
1819 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1820 "Statistics\\D-Layer2\\X-Frames");
1821 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1822 &pLib->InterfaceStat.d2.X_Frames;
1823
1824 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1825 "Statistics\\D-Layer2\\X-Bytes");
1826 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1827 &pLib->InterfaceStat.d2.X_Bytes;
1828
1829 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1830 "Statistics\\D-Layer2\\X-Errors");
1831 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1832 &pLib->InterfaceStat.d2.X_Errors;
1833
1834 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1835 "Statistics\\D-Layer2\\R-Frames");
1836 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1837 &pLib->InterfaceStat.d2.R_Frames;
1838
1839 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1840 "Statistics\\D-Layer2\\R-Bytes");
1841 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1842 &pLib->InterfaceStat.d2.R_Bytes;
1843
1844 strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1845 "Statistics\\D-Layer2\\R-Errors");
1846 pLib->parse_table[pLib->cur_parse_entry++].variable = \
1847 &pLib->InterfaceStat.d2.R_Errors;
1848
1849
1850 pLib->statistic_parse_last = pLib->cur_parse_entry - 1;
1851}
1852
1853static void diva_trace_error(diva_strace_context_t *pLib,
1854 int error, const char *file, int line) {
1855 if (pLib->user_proc_table.error_notify_proc) {
1856 (*(pLib->user_proc_table.error_notify_proc))(\
1857 pLib->user_proc_table.user_context,
1858 &pLib->instance, pLib->Adapter,
1859 error, file, line);
1860 }
1861}
1862
1863/*
1864 Delivery notification to user
1865*/
1866static void diva_trace_notify_user(diva_strace_context_t *pLib,
1867 int Channel,
1868 int notify_subject) {
1869 if (pLib->user_proc_table.notify_proc) {
1870 (*(pLib->user_proc_table.notify_proc))(pLib->user_proc_table.user_context,
1871 &pLib->instance,
1872 pLib->Adapter,
1873 &pLib->lines[Channel],
1874 notify_subject);
1875 }
1876}
1877
1878/*
1879 Read variable value to they destination based on the variable type
1880*/
1881static int diva_trace_read_variable(diva_man_var_header_t *pVar,
1882 void *variable) {
1883 switch (pVar->type) {
1884 case 0x03: /* MI_ASCIIZ - syting */
1885 return (diva_strace_read_asz(pVar, (char *)variable));
1886 case 0x04: /* MI_ASCII - string */
1887 return (diva_strace_read_asc(pVar, (char *)variable));
1888 case 0x05: /* MI_NUMBER - counted sequence of bytes */
1889 return (diva_strace_read_ie(pVar, (diva_trace_ie_t *)variable));
1890 case 0x81: /* MI_INT - signed integer */
1891 return (diva_strace_read_int(pVar, (int *)variable));
1892 case 0x82: /* MI_UINT - unsigned integer */
1893 return (diva_strace_read_uint(pVar, (dword *)variable));
1894 case 0x83: /* MI_HINT - unsigned integer, hex representetion */
1895 return (diva_strace_read_uint(pVar, (dword *)variable));
1896 case 0x87: /* MI_BITFLD - unsigned integer, bit representation */
1897 return (diva_strace_read_uint(pVar, (dword *)variable));
1898 }
1899
1900 /*
1901 This type of variable is not handled, indicate error
1902 Or one problem in management interface, or in application recodeing
1903 table, or this application should handle it.
1904 */
1905 return (-1);
1906}
1907
1908/*
1909 Read signed integer to destination
1910*/
1911static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var) {
1912 byte *ptr = (char *)&pVar->path_length;
1913 int value;
1914
1915 ptr += (pVar->path_length + 1);
1916
1917 switch (pVar->value_length) {
1918 case 1:
1919 value = *(char *)ptr;
1920 break;
1921
1922 case 2:
1923 value = (short)GET_WORD(ptr);
1924 break;
1925
1926 case 4:
1927 value = (int)GET_DWORD(ptr);
1928 break;
1929
1930 default:
1931 return (-1);
1932 }
1933
1934 *var = value;
1935
1936 return (0);
1937}
1938
1939static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var) {
1940 byte *ptr = (char *)&pVar->path_length;
1941 dword value;
1942
1943 ptr += (pVar->path_length + 1);
1944
1945 switch (pVar->value_length) {
1946 case 1:
1947 value = (byte)(*ptr);
1948 break;
1949
1950 case 2:
1951 value = (word)GET_WORD(ptr);
1952 break;
1953
1954 case 3:
1955 value = (dword)GET_DWORD(ptr);
1956 value &= 0x00ffffff;
1957 break;
1958
1959 case 4:
1960 value = (dword)GET_DWORD(ptr);
1961 break;
1962
1963 default:
1964 return (-1);
1965 }
1966
1967 *var = value;
1968
1969 return (0);
1970}
1971
1972/*
1973 Read zero terminated ASCII string
1974*/
1975static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var) {
1976 char *ptr = (char *)&pVar->path_length;
1977 int length;
1978
1979 ptr += (pVar->path_length + 1);
1980
1981 if (!(length = pVar->value_length)) {
1982 length = strlen(ptr);
1983 }
1984 memcpy(var, ptr, length);
1985 var[length] = 0;
1986
1987 return (0);
1988}
1989
1990/*
1991 Read counted (with leading length byte) ASCII string
1992*/
1993static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var) {
1994 char *ptr = (char *)&pVar->path_length;
1995
1996 ptr += (pVar->path_length + 1);
1997 memcpy(var, ptr + 1, *ptr);
1998 var[(int)*ptr] = 0;
1999
2000 return (0);
2001}
2002
2003/*
2004 Read one information element - i.e. one string of byte values with
2005 one length byte in front
2006*/
2007static int diva_strace_read_ie(diva_man_var_header_t *pVar,
2008 diva_trace_ie_t *var) {
2009 char *ptr = (char *)&pVar->path_length;
2010
2011 ptr += (pVar->path_length + 1);
2012
2013 var->length = *ptr;
2014 memcpy(&var->data[0], ptr + 1, *ptr);
2015
2016 return (0);
2017}
2018
2019static int SuperTraceSetAudioTap(void *hLib, int Channel, int on) {
2020 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2021
2022 if ((Channel < 1) || (Channel > pLib->Channels)) {
2023 return (-1);
2024 }
2025 Channel--;
2026
2027 if (on) {
2028 pLib->audio_tap_mask |= (1L << Channel);
2029 } else {
2030 pLib->audio_tap_mask &= ~(1L << Channel);
2031 }
2032
2033 /*
2034 EYE patterns have TM_M_DATA set as additional
2035 condition
2036 */
2037 if (pLib->audio_tap_mask) {
2038 pLib->trace_event_mask |= TM_M_DATA;
2039 } else {
2040 pLib->trace_event_mask &= ~TM_M_DATA;
2041 }
2042
2043 return (ScheduleNextTraceRequest(pLib));
2044}
2045
2046static int SuperTraceSetBChannel(void *hLib, int Channel, int on) {
2047 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2048
2049 if ((Channel < 1) || (Channel > pLib->Channels)) {
2050 return (-1);
2051 }
2052 Channel--;
2053
2054 if (on) {
2055 pLib->bchannel_trace_mask |= (1L << Channel);
2056 } else {
2057 pLib->bchannel_trace_mask &= ~(1L << Channel);
2058 }
2059
2060 return (ScheduleNextTraceRequest(pLib));
2061}
2062
2063static int SuperTraceSetDChannel(void *hLib, int on) {
2064 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2065
2066 if (on) {
2067 pLib->trace_event_mask |= (TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
2068 } else {
2069 pLib->trace_event_mask &= ~(TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
2070 }
2071
2072 return (ScheduleNextTraceRequest(pLib));
2073}
2074
2075static int SuperTraceSetInfo(void *hLib, int on) {
2076 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2077
2078 if (on) {
2079 pLib->trace_event_mask |= TM_STRING;
2080 } else {
2081 pLib->trace_event_mask &= ~TM_STRING;
2082 }
2083
2084 return (ScheduleNextTraceRequest(pLib));
2085}
2086
2087static int SuperTraceClearCall(void *hLib, int Channel) {
2088 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2089
2090 if ((Channel < 1) || (Channel > pLib->Channels)) {
2091 return (-1);
2092 }
2093 Channel--;
2094
2095 pLib->clear_call_command |= (1L << Channel);
2096
2097 return (ScheduleNextTraceRequest(pLib));
2098}
2099
2100/*
2101 Parse and update cumulative statistice
2102*/
2103static int diva_ifc_statistics(diva_strace_context_t *pLib,
2104 diva_man_var_header_t *pVar) {
2105 diva_man_var_header_t *cur;
2106 int i, one_updated = 0, mdm_updated = 0, fax_updated = 0;
2107
2108 for (i = pLib->statistic_parse_first; i <= pLib->statistic_parse_last; i++) {
2109 if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
2110 if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
2111 diva_trace_error(pLib, -3 , __FILE__, __LINE__);
2112 return (-1);
2113 }
2114 one_updated = 1;
2115 if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) {
2116 mdm_updated = 1;
2117 }
2118 if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) {
2119 fax_updated = 1;
2120 }
2121 }
2122 }
2123
2124 /*
2125 We do not use first event to notify user - this is the event that is
2126 generated as result of EVENT ON operation and is used only to initialize
2127 internal variables of application
2128 */
2129 if (mdm_updated) {
2130 diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE);
2131 } else if (fax_updated) {
2132 diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE);
2133 } else if (one_updated) {
2134 diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE);
2135 }
2136
2137 return (one_updated ? 0 : -1);
2138}
2139
2140static int SuperTraceGetOutgoingCallStatistics(void *hLib) {
2141 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2142 pLib->outgoing_ifc_stats = 1;
2143 return (ScheduleNextTraceRequest(pLib));
2144}
2145
2146static int SuperTraceGetIncomingCallStatistics(void *hLib) {
2147 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2148 pLib->incoming_ifc_stats = 1;
2149 return (ScheduleNextTraceRequest(pLib));
2150}
2151
2152static int SuperTraceGetModemStatistics(void *hLib) {
2153 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2154 pLib->modem_ifc_stats = 1;
2155 return (ScheduleNextTraceRequest(pLib));
2156}
2157
2158static int SuperTraceGetFaxStatistics(void *hLib) {
2159 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2160 pLib->fax_ifc_stats = 1;
2161 return (ScheduleNextTraceRequest(pLib));
2162}
2163
2164static int SuperTraceGetBLayer1Statistics(void *hLib) {
2165 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2166 pLib->b1_ifc_stats = 1;
2167 return (ScheduleNextTraceRequest(pLib));
2168}
2169
2170static int SuperTraceGetBLayer2Statistics(void *hLib) {
2171 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2172 pLib->b2_ifc_stats = 1;
2173 return (ScheduleNextTraceRequest(pLib));
2174}
2175
2176static int SuperTraceGetDLayer1Statistics(void *hLib) {
2177 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2178 pLib->d1_ifc_stats = 1;
2179 return (ScheduleNextTraceRequest(pLib));
2180}
2181
2182static int SuperTraceGetDLayer2Statistics(void *hLib) {
2183 diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
2184 pLib->d2_ifc_stats = 1;
2185 return (ScheduleNextTraceRequest(pLib));
2186}
2187
2188dword DivaSTraceGetMemotyRequirement(int channels) {
2189 dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
2190 STAT_PARSE_ENTRIES + \
2191 LINE_PARSE_ENTRIES + 1) * channels;
2192 return (sizeof(diva_strace_context_t) + \
2193 (parse_entries * sizeof(diva_strace_path2action_t)));
2194}
diff --git a/drivers/isdn/hardware/eicon/maintidi.h b/drivers/isdn/hardware/eicon/maintidi.h
deleted file mode 100644
index 2b46147c5532..000000000000
--- a/drivers/isdn/hardware/eicon/maintidi.h
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Networks, 2000.
4 *
5 This source file is supplied for the use with
6 Eicon Networks range of DIVA Server Adapters.
7 *
8 Eicon File Revision : 1.9
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, or (at your option)
13 any later version.
14 *
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the 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 */
25#ifndef __DIVA_EICON_TRACE_IDI_IFC_H__
26#define __DIVA_EICON_TRACE_IDI_IFC_H__
27
28void *SuperTraceOpenAdapter(int AdapterNumber);
29int SuperTraceCloseAdapter(void *AdapterHandle);
30int SuperTraceWrite(void *AdapterHandle,
31 const void *data, int length);
32int SuperTraceReadRequest(void *AdapterHandle, const char *name, byte *data);
33int SuperTraceGetNumberOfChannels(void *AdapterHandle);
34int SuperTraceASSIGN(void *AdapterHandle, byte *data);
35int SuperTraceREMOVE(void *AdapterHandle);
36int SuperTraceTraceOnRequest(void *hAdapter, const char *name, byte *data);
37int SuperTraceWriteVar(void *AdapterHandle,
38 byte *data,
39 const char *name,
40 void *var,
41 byte type,
42 byte var_length);
43int SuperTraceExecuteRequest(void *AdapterHandle,
44 const char *name,
45 byte *data);
46
47typedef struct _diva_strace_path2action {
48 char path[64]; /* Full path to variable */
49 void *variable; /* Variable that will receive value */
50} diva_strace_path2action_t;
51
52#define DIVA_MAX_MANAGEMENT_TRANSFER_SIZE 4096
53
54typedef struct _diva_strace_context {
55 diva_strace_library_interface_t instance;
56
57 int Adapter;
58 void *hAdapter;
59
60 int Channels;
61 int req_busy;
62
63 ENTITY e;
64 IDI_CALL request;
65 BUFFERS XData;
66 BUFFERS RData;
67 byte buffer[DIVA_MAX_MANAGEMENT_TRANSFER_SIZE + 1];
68 int removal_state;
69 int general_b_ch_event;
70 int general_fax_event;
71 int general_mdm_event;
72
73 byte rc_ok;
74
75 /*
76 Initialization request state machine
77 */
78 int ChannelsTraceActive;
79 int ModemTraceActive;
80 int FaxTraceActive;
81 int IncomingCallsCallsActive;
82 int IncomingCallsConnectedActive;
83 int OutgoingCallsCallsActive;
84 int OutgoingCallsConnectedActive;
85
86 int trace_mask_init;
87 int audio_trace_init;
88 int bchannel_init;
89 int trace_length_init;
90 int trace_on;
91 int trace_events_down;
92 int l1_trace;
93 int l2_trace;
94
95 /*
96 Trace\Event Enable
97 */
98 word trace_event_mask;
99 word current_trace_event_mask;
100
101 dword audio_tap_mask;
102 dword current_audio_tap_mask;
103 dword current_eye_pattern_mask;
104 int audio_tap_pending;
105 int eye_pattern_pending;
106
107 dword bchannel_trace_mask;
108 dword current_bchannel_trace_mask;
109
110
111 diva_trace_line_state_t lines[30];
112
113 int parse_entries;
114 int cur_parse_entry;
115 diva_strace_path2action_t *parse_table;
116
117 diva_trace_library_user_interface_t user_proc_table;
118
119 int line_parse_entry_first[30];
120 int line_parse_entry_last[30];
121
122 int modem_parse_entry_first[30];
123 int modem_parse_entry_last[30];
124
125 int fax_parse_entry_first[30];
126 int fax_parse_entry_last[30];
127
128 int statistic_parse_first;
129 int statistic_parse_last;
130
131 int mdm_statistic_parse_first;
132 int mdm_statistic_parse_last;
133
134 int fax_statistic_parse_first;
135 int fax_statistic_parse_last;
136
137 dword line_init_event;
138 dword modem_init_event;
139 dword fax_init_event;
140
141 dword pending_line_status;
142 dword pending_modem_status;
143 dword pending_fax_status;
144
145 dword clear_call_command;
146
147 int outgoing_ifc_stats;
148 int incoming_ifc_stats;
149 int modem_ifc_stats;
150 int fax_ifc_stats;
151 int b1_ifc_stats;
152 int b2_ifc_stats;
153 int d1_ifc_stats;
154 int d2_ifc_stats;
155
156 diva_trace_interface_state_t Interface;
157 diva_ifc_statistics_t InterfaceStat;
158} diva_strace_context_t;
159
160typedef struct _diva_man_var_header {
161 byte escape;
162 byte length;
163 byte management_id;
164 byte type;
165 byte attribute;
166 byte status;
167 byte value_length;
168 byte path_length;
169} diva_man_var_header_t;
170
171#endif
diff --git a/drivers/isdn/hardware/eicon/man_defs.h b/drivers/isdn/hardware/eicon/man_defs.h
deleted file mode 100644
index 249c471700e7..000000000000
--- a/drivers/isdn/hardware/eicon/man_defs.h
+++ /dev/null
@@ -1,133 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Networks, 2002.
4 *
5 This source file is supplied for the use with
6 Eicon Networks range of DIVA Server Adapters.
7 *
8 Eicon File Revision : 1.9
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, or (at your option)
13 any later version.
14 *
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the 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 */
25/* Definitions for use with the Management Information Element */
26
27/*------------------------------------------------------------------*/
28/* Management information element */
29/* ---------------------------------------------------------- */
30/* Byte Coding Comment */
31/* ---------------------------------------------------------- */
32/* 0 | 0 1 1 1 1 1 1 1 | ESC */
33/* 1 | 0 x x x x x x x | Length of information element (m-1) */
34/* 2 | 1 0 0 0 0 0 0 0 | Management Information Id */
35/* 3 | x x x x x x x x | Type */
36/* 4 | x x x x x x x x | Attribute */
37/* 5 | x x x x x x x x | Status */
38/* 6 | x x x x x x x x | Variable Value Length (m-n) */
39/* 7 | x x x x x x x x | Path / Variable Name String Length (n-8)*/
40/* 8..n | x x x x x x x x | Path/Node Name String separated by '\' */
41/* n..m | x x x x x x x x | Variable content */
42/*------------------------------------------------------------------*/
43
44/*------------------------------------------------------------------*/
45/* Type Field */
46/* */
47/* MAN_READ: not used */
48/* MAN_WRITE: not used */
49/* MAN_EVENT_ON: not used */
50/* MAN_EVENT_OFF: not used */
51/* MAN_INFO_IND: type of variable */
52/* MAN_EVENT_IND: type of variable */
53/* MAN_TRACE_IND not used */
54/*------------------------------------------------------------------*/
55#define MI_DIR 0x01 /* Directory string (zero terminated) */
56#define MI_EXECUTE 0x02 /* Executable function (has no value) */
57#define MI_ASCIIZ 0x03 /* Zero terminated string */
58#define MI_ASCII 0x04 /* String, first byte is length */
59#define MI_NUMBER 0x05 /* Number string, first byte is length*/
60#define MI_TRACE 0x06 /* Trace information, format see below*/
61
62#define MI_FIXED_LENGTH 0x80 /* get length from MAN_INFO max_len */
63#define MI_INT 0x81 /* number to display as signed int */
64#define MI_UINT 0x82 /* number to display as unsigned int */
65#define MI_HINT 0x83 /* number to display in hex format */
66#define MI_HSTR 0x84 /* number to display as a hex string */
67#define MI_BOOLEAN 0x85 /* number to display as boolean */
68#define MI_IP_ADDRESS 0x86 /* number to display as IP address */
69#define MI_BITFLD 0x87 /* number to display as bit field */
70#define MI_SPID_STATE 0x88 /* state# of SPID initialisation */
71
72/*------------------------------------------------------------------*/
73/* Attribute Field */
74/* */
75/* MAN_READ: not used */
76/* MAN_WRITE: not used */
77/* MAN_EVENT_ON: not used */
78/* MAN_EVENT_OFF: not used */
79/* MAN_INFO_IND: set according to capabilities of that variable */
80/* MAN_EVENT_IND: not used */
81/* MAN_TRACE_IND not used */
82/*------------------------------------------------------------------*/
83#define MI_WRITE 0x01 /* Variable is writeable */
84#define MI_EVENT 0x02 /* Variable can indicate changes */
85
86/*------------------------------------------------------------------*/
87/* Status Field */
88/* */
89/* MAN_READ: not used */
90/* MAN_WRITE: not used */
91/* MAN_EVENT_ON: not used */
92/* MAN_EVENT_OFF: not used */
93/* MAN_INFO_IND: set according to the actual status */
94/* MAN_EVENT_IND: set according to the actual statu */
95/* MAN_TRACE_IND not used */
96/*------------------------------------------------------------------*/
97#define MI_LOCKED 0x01 /* write protected by another instance*/
98#define MI_EVENT_ON 0x02 /* Event logging switched on */
99#define MI_PROTECTED 0x04 /* write protected by this instance */
100
101/*------------------------------------------------------------------*/
102/* Data Format used for MAN_TRACE_IND (no MI-element used) */
103/*------------------------------------------------------------------*/
104typedef struct mi_xlog_hdr_s MI_XLOG_HDR;
105struct mi_xlog_hdr_s
106{
107 unsigned long time; /* Timestamp in msec units */
108 unsigned short size; /* Size of data that follows */
109 unsigned short code; /* code of trace event */
110}; /* unspecified data follows this header */
111
112/*------------------------------------------------------------------*/
113/* Trace mask definitions for trace events except B channel and */
114/* debug trace events */
115/*------------------------------------------------------------------*/
116#define TM_D_CHAN 0x0001 /* D-Channel (D-.) Code 3,4 */
117#define TM_L_LAYER 0x0002 /* Low Layer (LL) Code 6,7 */
118#define TM_N_LAYER 0x0004 /* Network Layer (N) Code 14,15 */
119#define TM_DL_ERR 0x0008 /* Data Link Error (MDL) Code 9 */
120#define TM_LAYER1 0x0010 /* Layer 1 Code 20 */
121#define TM_C_COMM 0x0020 /* Call Comment (SIG) Code 5,21,22 */
122#define TM_M_DATA 0x0040 /* Modulation Data (EYE) Code 23 */
123#define TM_STRING 0x0080 /* Sting data Code 24 */
124#define TM_N_USED2 0x0100 /* not used */
125#define TM_N_USED3 0x0200 /* not used */
126#define TM_N_USED4 0x0400 /* not used */
127#define TM_N_USED5 0x0800 /* not used */
128#define TM_N_USED6 0x1000 /* not used */
129#define TM_N_USED7 0x2000 /* not used */
130#define TM_N_USED8 0x4000 /* not used */
131#define TM_REST 0x8000 /* Codes 10,11,12,13,16,18,19,128,129 */
132
133/*------ End of file -----------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/mdm_msg.h b/drivers/isdn/hardware/eicon/mdm_msg.h
deleted file mode 100644
index 0e6b2e009a74..000000000000
--- a/drivers/isdn/hardware/eicon/mdm_msg.h
+++ /dev/null
@@ -1,346 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __EICON_MDM_MSG_H__
27#define __EICON_MDM_MSG_H__
28#define DSP_UDATA_INDICATION_DCD_OFF 0x01
29#define DSP_UDATA_INDICATION_DCD_ON 0x02
30#define DSP_UDATA_INDICATION_CTS_OFF 0x03
31#define DSP_UDATA_INDICATION_CTS_ON 0x04
32/* =====================================================================
33 DCD_OFF Message:
34 <word> time of DCD off (sampled from counter at 8kHz)
35 DCD_ON Message:
36 <word> time of DCD on (sampled from counter at 8kHz)
37 <byte> connected norm
38 <word> connected options
39 <dword> connected speed (bit/s, max of tx and rx speed)
40 <word> roundtrip delay (ms)
41 <dword> connected speed tx (bit/s)
42 <dword> connected speed rx (bit/s)
43 Size of this message == 19 bytes, but we will receive only 11
44 ===================================================================== */
45#define DSP_CONNECTED_NORM_UNSPECIFIED 0
46#define DSP_CONNECTED_NORM_V21 1
47#define DSP_CONNECTED_NORM_V23 2
48#define DSP_CONNECTED_NORM_V22 3
49#define DSP_CONNECTED_NORM_V22_BIS 4
50#define DSP_CONNECTED_NORM_V32_BIS 5
51#define DSP_CONNECTED_NORM_V34 6
52#define DSP_CONNECTED_NORM_V8 7
53#define DSP_CONNECTED_NORM_BELL_212A 8
54#define DSP_CONNECTED_NORM_BELL_103 9
55#define DSP_CONNECTED_NORM_V29_LEASED_LINE 10
56#define DSP_CONNECTED_NORM_V33_LEASED_LINE 11
57#define DSP_CONNECTED_NORM_V90 12
58#define DSP_CONNECTED_NORM_V21_CH2 13
59#define DSP_CONNECTED_NORM_V27_TER 14
60#define DSP_CONNECTED_NORM_V29 15
61#define DSP_CONNECTED_NORM_V33 16
62#define DSP_CONNECTED_NORM_V17 17
63#define DSP_CONNECTED_NORM_V32 18
64#define DSP_CONNECTED_NORM_K56_FLEX 19
65#define DSP_CONNECTED_NORM_X2 20
66#define DSP_CONNECTED_NORM_V18 21
67#define DSP_CONNECTED_NORM_V18_LOW_HIGH 22
68#define DSP_CONNECTED_NORM_V18_HIGH_LOW 23
69#define DSP_CONNECTED_NORM_V21_LOW_HIGH 24
70#define DSP_CONNECTED_NORM_V21_HIGH_LOW 25
71#define DSP_CONNECTED_NORM_BELL103_LOW_HIGH 26
72#define DSP_CONNECTED_NORM_BELL103_HIGH_LOW 27
73#define DSP_CONNECTED_NORM_V23_75_1200 28
74#define DSP_CONNECTED_NORM_V23_1200_75 29
75#define DSP_CONNECTED_NORM_EDT_110 30
76#define DSP_CONNECTED_NORM_BAUDOT_45 31
77#define DSP_CONNECTED_NORM_BAUDOT_47 32
78#define DSP_CONNECTED_NORM_BAUDOT_50 33
79#define DSP_CONNECTED_NORM_DTMF 34
80#define DSP_CONNECTED_NORM_V18_RESERVED_13 35
81#define DSP_CONNECTED_NORM_V18_RESERVED_14 36
82#define DSP_CONNECTED_NORM_V18_RESERVED_15 37
83#define DSP_CONNECTED_NORM_VOWN 38
84#define DSP_CONNECTED_NORM_V23_OFF_HOOK 39
85#define DSP_CONNECTED_NORM_V23_ON_HOOK 40
86#define DSP_CONNECTED_NORM_VOWN_RESERVED_3 41
87#define DSP_CONNECTED_NORM_VOWN_RESERVED_4 42
88#define DSP_CONNECTED_NORM_VOWN_RESERVED_5 43
89#define DSP_CONNECTED_NORM_VOWN_RESERVED_6 44
90#define DSP_CONNECTED_NORM_VOWN_RESERVED_7 45
91#define DSP_CONNECTED_NORM_VOWN_RESERVED_8 46
92#define DSP_CONNECTED_NORM_VOWN_RESERVED_9 47
93#define DSP_CONNECTED_NORM_VOWN_RESERVED_10 48
94#define DSP_CONNECTED_NORM_VOWN_RESERVED_11 49
95#define DSP_CONNECTED_NORM_VOWN_RESERVED_12 50
96#define DSP_CONNECTED_NORM_VOWN_RESERVED_13 51
97#define DSP_CONNECTED_NORM_VOWN_RESERVED_14 52
98#define DSP_CONNECTED_NORM_VOWN_RESERVED_15 53
99#define DSP_CONNECTED_NORM_VOWN_RESERVED_16 54
100#define DSP_CONNECTED_NORM_VOWN_RESERVED_17 55
101#define DSP_CONNECTED_NORM_VOWN_RESERVED_18 56
102#define DSP_CONNECTED_NORM_VOWN_RESERVED_19 57
103#define DSP_CONNECTED_NORM_VOWN_RESERVED_20 58
104#define DSP_CONNECTED_NORM_VOWN_RESERVED_21 59
105#define DSP_CONNECTED_NORM_VOWN_RESERVED_22 60
106#define DSP_CONNECTED_NORM_VOWN_RESERVED_23 61
107#define DSP_CONNECTED_NORM_VOWN_RESERVED_24 62
108#define DSP_CONNECTED_NORM_VOWN_RESERVED_25 63
109#define DSP_CONNECTED_NORM_VOWN_RESERVED_26 64
110#define DSP_CONNECTED_NORM_VOWN_RESERVED_27 65
111#define DSP_CONNECTED_NORM_VOWN_RESERVED_28 66
112#define DSP_CONNECTED_NORM_VOWN_RESERVED_29 67
113#define DSP_CONNECTED_NORM_VOWN_RESERVED_30 68
114#define DSP_CONNECTED_NORM_VOWN_RESERVED_31 69
115#define DSP_CONNECTED_OPTION_TRELLIS 0x0001
116#define DSP_CONNECTED_OPTION_V42_TRANS 0x0002
117#define DSP_CONNECTED_OPTION_V42_LAPM 0x0004
118#define DSP_CONNECTED_OPTION_SHORT_TRAIN 0x0008
119#define DSP_CONNECTED_OPTION_TALKER_ECHO_PROTECT 0x0010
120#define DSP_CONNECTED_OPTION_V42BIS 0x0020
121#define DSP_CONNECTED_OPTION_MNP2 0x0040
122#define DSP_CONNECTED_OPTION_MNP3 0x0080
123#define DSP_CONNECTED_OPTION_MNP4 0x00c0
124#define DSP_CONNECTED_OPTION_MNP5 0x0100
125#define DSP_CONNECTED_OPTION_MNP10 0x0200
126#define DSP_CONNECTED_OPTION_MASK_V42 0x0024
127#define DSP_CONNECTED_OPTION_MASK_MNP 0x03c0
128#define DSP_CONNECTED_OPTION_MASK_ERROR_CORRECT 0x03e4
129#define DSP_CONNECTED_OPTION_MASK_COMPRESSION 0x0320
130#define DSP_UDATA_INDICATION_DISCONNECT 5
131/*
132 returns:
133 <byte> cause
134*/
135/* ==========================================================
136 DLC: B2 modem configuration
137 ========================================================== */
138/*
139 Fields in assign DLC information element for modem protocol V.42/MNP:
140 <byte> length of information element
141 <word> information field length
142 <byte> address A (not used, default 3)
143 <byte> address B (not used, default 1)
144 <byte> modulo mode (not used, default 7)
145 <byte> window size (not used, default 7)
146 <word> XID length (not used, default 0)
147 ... XID information (not used, default empty)
148 <byte> modem protocol negotiation options
149 <byte> modem protocol options
150 <byte> modem protocol break configuration
151 <byte> modem protocol application options
152*/
153#define DLC_MODEMPROT_DISABLE_V42_V42BIS 0x01
154#define DLC_MODEMPROT_DISABLE_MNP_MNP5 0x02
155#define DLC_MODEMPROT_REQUIRE_PROTOCOL 0x04
156#define DLC_MODEMPROT_DISABLE_V42_DETECT 0x08
157#define DLC_MODEMPROT_DISABLE_COMPRESSION 0x10
158#define DLC_MODEMPROT_REQUIRE_PROTOCOL_V34UP 0x20
159#define DLC_MODEMPROT_NO_PROTOCOL_IF_1200 0x01
160#define DLC_MODEMPROT_BUFFER_IN_V42_DETECT 0x02
161#define DLC_MODEMPROT_DISABLE_V42_SREJ 0x04
162#define DLC_MODEMPROT_DISABLE_MNP3 0x08
163#define DLC_MODEMPROT_DISABLE_MNP4 0x10
164#define DLC_MODEMPROT_DISABLE_MNP10 0x20
165#define DLC_MODEMPROT_NO_PROTOCOL_IF_V22BIS 0x40
166#define DLC_MODEMPROT_NO_PROTOCOL_IF_V32BIS 0x80
167#define DLC_MODEMPROT_BREAK_DISABLED 0x00
168#define DLC_MODEMPROT_BREAK_NORMAL 0x01
169#define DLC_MODEMPROT_BREAK_EXPEDITED 0x02
170#define DLC_MODEMPROT_BREAK_DESTRUCTIVE 0x03
171#define DLC_MODEMPROT_BREAK_CONFIG_MASK 0x03
172#define DLC_MODEMPROT_APPL_EARLY_CONNECT 0x01
173#define DLC_MODEMPROT_APPL_PASS_INDICATIONS 0x02
174/* ==========================================================
175 CAI parameters used for the modem L1 configuration
176 ========================================================== */
177/*
178 Fields in assign CAI information element:
179 <byte> length of information element
180 <byte> info field and B-channel hardware
181 <byte> rate adaptation bit rate
182 <byte> async framing parameters
183 <byte> reserved
184 <word> packet length
185 <byte> modem line taking options
186 <byte> modem modulation negotiation parameters
187 <byte> modem modulation options
188 <byte> modem disabled modulations mask low
189 <byte> modem disabled modulations mask high
190 <byte> modem enabled modulations mask
191 <word> modem min TX speed
192 <word> modem max TX speed
193 <word> modem min RX speed
194 <word> modem max RX speed
195 <byte> modem disabled symbol rates mask
196 <byte> modem info options mask
197 <byte> modem transmit level adjust
198 <byte> modem speaker parameters
199 <word> modem private debug config
200 <struct> modem reserved
201 <struct> v18 config parameters
202 <struct> v18 probing sequence
203 <struct> v18 probing message
204*/
205#define DSP_CAI_HARDWARE_HDLC_64K 0x05
206#define DSP_CAI_HARDWARE_HDLC_56K 0x08
207#define DSP_CAI_HARDWARE_TRANSP 0x09
208#define DSP_CAI_HARDWARE_V110_SYNC 0x0c
209#define DSP_CAI_HARDWARE_V110_ASYNC 0x0d
210#define DSP_CAI_HARDWARE_HDLC_128K 0x0f
211#define DSP_CAI_HARDWARE_FAX 0x10
212#define DSP_CAI_HARDWARE_MODEM_ASYNC 0x11
213#define DSP_CAI_HARDWARE_MODEM_SYNC 0x12
214#define DSP_CAI_HARDWARE_V110_HDLCA 0x13
215#define DSP_CAI_HARDWARE_ADVANCED_VOICE 0x14
216#define DSP_CAI_HARDWARE_TRANSP_DTMF 0x16
217#define DSP_CAI_HARDWARE_DTMF_VOICE_ISDN 0x17
218#define DSP_CAI_HARDWARE_DTMF_VOICE_LOCAL 0x18
219#define DSP_CAI_HARDWARE_MASK 0x3f
220#define DSP_CAI_ENABLE_INFO_INDICATIONS 0x80
221#define DSP_CAI_RATE_ADAPTATION_300 0x00
222#define DSP_CAI_RATE_ADAPTATION_600 0x01
223#define DSP_CAI_RATE_ADAPTATION_1200 0x02
224#define DSP_CAI_RATE_ADAPTATION_2400 0x03
225#define DSP_CAI_RATE_ADAPTATION_4800 0x04
226#define DSP_CAI_RATE_ADAPTATION_9600 0x05
227#define DSP_CAI_RATE_ADAPTATION_19200 0x06
228#define DSP_CAI_RATE_ADAPTATION_38400 0x07
229#define DSP_CAI_RATE_ADAPTATION_48000 0x08
230#define DSP_CAI_RATE_ADAPTATION_56000 0x09
231#define DSP_CAI_RATE_ADAPTATION_7200 0x0a
232#define DSP_CAI_RATE_ADAPTATION_14400 0x0b
233#define DSP_CAI_RATE_ADAPTATION_28800 0x0c
234#define DSP_CAI_RATE_ADAPTATION_12000 0x0d
235#define DSP_CAI_RATE_ADAPTATION_1200_75 0x0e
236#define DSP_CAI_RATE_ADAPTATION_75_1200 0x0f
237#define DSP_CAI_RATE_ADAPTATION_MASK 0x0f
238#define DSP_CAI_ASYNC_PARITY_ENABLE 0x01
239#define DSP_CAI_ASYNC_PARITY_SPACE 0x00
240#define DSP_CAI_ASYNC_PARITY_ODD 0x02
241#define DSP_CAI_ASYNC_PARITY_EVEN 0x04
242#define DSP_CAI_ASYNC_PARITY_MARK 0x06
243#define DSP_CAI_ASYNC_PARITY_MASK 0x06
244#define DSP_CAI_ASYNC_ONE_STOP_BIT 0x00
245#define DSP_CAI_ASYNC_TWO_STOP_BITS 0x20
246#define DSP_CAI_ASYNC_CHAR_LENGTH_8 0x00
247#define DSP_CAI_ASYNC_CHAR_LENGTH_7 0x40
248#define DSP_CAI_ASYNC_CHAR_LENGTH_6 0x80
249#define DSP_CAI_ASYNC_CHAR_LENGTH_5 0xc0
250#define DSP_CAI_ASYNC_CHAR_LENGTH_MASK 0xc0
251#define DSP_CAI_MODEM_LEASED_LINE_MODE 0x01
252#define DSP_CAI_MODEM_4_WIRE_OPERATION 0x02
253#define DSP_CAI_MODEM_DISABLE_BUSY_DETECT 0x04
254#define DSP_CAI_MODEM_DISABLE_CALLING_TONE 0x08
255#define DSP_CAI_MODEM_DISABLE_ANSWER_TONE 0x10
256#define DSP_CAI_MODEM_ENABLE_DIAL_TONE_DET 0x20
257#define DSP_CAI_MODEM_USE_POTS_INTERFACE 0x40
258#define DSP_CAI_MODEM_FORCE_RAY_TAYLOR_FAX 0x80
259#define DSP_CAI_MODEM_NEGOTIATE_HIGHEST 0x00
260#define DSP_CAI_MODEM_NEGOTIATE_DISABLED 0x01
261#define DSP_CAI_MODEM_NEGOTIATE_IN_CLASS 0x02
262#define DSP_CAI_MODEM_NEGOTIATE_V100 0x03
263#define DSP_CAI_MODEM_NEGOTIATE_V8 0x04
264#define DSP_CAI_MODEM_NEGOTIATE_V8BIS 0x05
265#define DSP_CAI_MODEM_NEGOTIATE_MASK 0x07
266#define DSP_CAI_MODEM_GUARD_TONE_NONE 0x00
267#define DSP_CAI_MODEM_GUARD_TONE_550HZ 0x40
268#define DSP_CAI_MODEM_GUARD_TONE_1800HZ 0x80
269#define DSP_CAI_MODEM_GUARD_TONE_MASK 0xc0
270#define DSP_CAI_MODEM_DISABLE_RETRAIN 0x01
271#define DSP_CAI_MODEM_DISABLE_STEPUPDOWN 0x02
272#define DSP_CAI_MODEM_DISABLE_SPLIT_SPEED 0x04
273#define DSP_CAI_MODEM_DISABLE_TRELLIS 0x08
274#define DSP_CAI_MODEM_ALLOW_RDL_TEST_LOOP 0x10
275#define DSP_CAI_MODEM_DISABLE_FLUSH_TIMER 0x40
276#define DSP_CAI_MODEM_REVERSE_DIRECTION 0x80
277#define DSP_CAI_MODEM_DISABLE_V21 0x01
278#define DSP_CAI_MODEM_DISABLE_V23 0x02
279#define DSP_CAI_MODEM_DISABLE_V22 0x04
280#define DSP_CAI_MODEM_DISABLE_V22BIS 0x08
281#define DSP_CAI_MODEM_DISABLE_V32 0x10
282#define DSP_CAI_MODEM_DISABLE_V32BIS 0x20
283#define DSP_CAI_MODEM_DISABLE_V34 0x40
284#define DSP_CAI_MODEM_DISABLE_V90 0x80
285#define DSP_CAI_MODEM_DISABLE_BELL103 0x01
286#define DSP_CAI_MODEM_DISABLE_BELL212A 0x02
287#define DSP_CAI_MODEM_DISABLE_VFC 0x04
288#define DSP_CAI_MODEM_DISABLE_K56FLEX 0x08
289#define DSP_CAI_MODEM_DISABLE_X2 0x10
290#define DSP_CAI_MODEM_ENABLE_V29FDX 0x01
291#define DSP_CAI_MODEM_ENABLE_V33 0x02
292#define DSP_CAI_MODEM_DISABLE_2400_SYMBOLS 0x01
293#define DSP_CAI_MODEM_DISABLE_2743_SYMBOLS 0x02
294#define DSP_CAI_MODEM_DISABLE_2800_SYMBOLS 0x04
295#define DSP_CAI_MODEM_DISABLE_3000_SYMBOLS 0x08
296#define DSP_CAI_MODEM_DISABLE_3200_SYMBOLS 0x10
297#define DSP_CAI_MODEM_DISABLE_3429_SYMBOLS 0x20
298#define DSP_CAI_MODEM_DISABLE_TX_REDUCTION 0x01
299#define DSP_CAI_MODEM_DISABLE_PRECODING 0x02
300#define DSP_CAI_MODEM_DISABLE_PREEMPHASIS 0x04
301#define DSP_CAI_MODEM_DISABLE_SHAPING 0x08
302#define DSP_CAI_MODEM_DISABLE_NONLINEAR_EN 0x10
303#define DSP_CAI_MODEM_SPEAKER_OFF 0x00
304#define DSP_CAI_MODEM_SPEAKER_DURING_TRAIN 0x01
305#define DSP_CAI_MODEM_SPEAKER_TIL_CONNECT 0x02
306#define DSP_CAI_MODEM_SPEAKER_ALWAYS_ON 0x03
307#define DSP_CAI_MODEM_SPEAKER_CONTROL_MASK 0x03
308#define DSP_CAI_MODEM_SPEAKER_VOLUME_MIN 0x00
309#define DSP_CAI_MODEM_SPEAKER_VOLUME_LOW 0x04
310#define DSP_CAI_MODEM_SPEAKER_VOLUME_HIGH 0x08
311#define DSP_CAI_MODEM_SPEAKER_VOLUME_MAX 0x0c
312#define DSP_CAI_MODEM_SPEAKER_VOLUME_MASK 0x0c
313/* ==========================================================
314 DCD/CTS State
315 ========================================================== */
316#define MDM_WANT_CONNECT_B3_ACTIVE_I 0x01
317#define MDM_NCPI_VALID 0x02
318#define MDM_NCPI_CTS_ON_RECEIVED 0x04
319#define MDM_NCPI_DCD_ON_RECEIVED 0x08
320/* ==========================================================
321 CAPI NCPI Constants
322 ========================================================== */
323#define MDM_NCPI_ECM_V42 0x0001
324#define MDM_NCPI_ECM_MNP 0x0002
325#define MDM_NCPI_TRANSPARENT 0x0004
326#define MDM_NCPI_COMPRESSED 0x0010
327/* ==========================================================
328 CAPI B2 Config Constants
329 ========================================================== */
330#define MDM_B2_DISABLE_V42bis 0x0001
331#define MDM_B2_DISABLE_MNP 0x0002
332#define MDM_B2_DISABLE_TRANS 0x0004
333#define MDM_B2_DISABLE_V42 0x0008
334#define MDM_B2_DISABLE_COMP 0x0010
335/* ==========================================================
336 CAPI B1 Config Constants
337 ========================================================== */
338#define MDM_CAPI_DISABLE_RETRAIN 0x0001
339#define MDM_CAPI_DISABLE_RING_TONE 0x0002
340#define MDM_CAPI_GUARD_1800 0x0004
341#define MDM_CAPI_GUARD_550 0x0008
342#define MDM_CAPI_NEG_V8 0x0003
343#define MDM_CAPI_NEG_V100 0x0002
344#define MDM_CAPI_NEG_MOD_CLASS 0x0001
345#define MDM_CAPI_NEG_DISABLED 0x0000
346#endif
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
deleted file mode 100644
index def7992a38e6..000000000000
--- a/drivers/isdn/hardware/eicon/message.c
+++ /dev/null
@@ -1,14954 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Networks, 2002.
4 *
5 This source file is supplied for the use with
6 Eicon Networks range of DIVA Server Adapters.
7 *
8 Eicon File Revision : 2.1
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, or (at your option)
13 any later version.
14 *
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the 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 */
25
26#include <linux/bitmap.h>
27
28#include "platform.h"
29#include "di_defs.h"
30#include "pc.h"
31#include "capi20.h"
32#include "divacapi.h"
33#include "mdm_msg.h"
34#include "divasync.h"
35
36#define FILE_ "MESSAGE.C"
37#define dprintf
38
39/*------------------------------------------------------------------*/
40/* This is options supported for all adapters that are server by */
41/* XDI driver. Allo it is not necessary to ask it from every adapter*/
42/* and it is not necessary to save it separate for every adapter */
43/* Macrose defined here have only local meaning */
44/*------------------------------------------------------------------*/
45static dword diva_xdi_extended_features = 0;
46
47#define DIVA_CAPI_USE_CMA 0x00000001
48#define DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR 0x00000002
49#define DIVA_CAPI_XDI_PROVIDES_NO_CANCEL 0x00000004
50#define DIVA_CAPI_XDI_PROVIDES_RX_DMA 0x00000008
51
52/*
53 CAPI can request to process all return codes self only if:
54 protocol code supports this && xdi supports this
55*/
56#define DIVA_CAPI_SUPPORTS_NO_CANCEL(__a__) (((__a__)->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) && ((__a__)->manufacturer_features & MANUFACTURER_FEATURE_OK_FC_LABEL) && (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_NO_CANCEL))
57
58/*------------------------------------------------------------------*/
59/* local function prototypes */
60/*------------------------------------------------------------------*/
61
62static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci);
63void AutomaticLaw(DIVA_CAPI_ADAPTER *);
64word CapiRelease(word);
65word CapiRegister(word);
66word api_put(APPL *, CAPI_MSG *);
67static word api_parse(byte *, word, byte *, API_PARSE *);
68static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out);
69static void api_load_msg(API_SAVE *in, API_PARSE *out);
70
71word api_remove_start(void);
72void api_remove_complete(void);
73
74static void plci_remove(PLCI *);
75static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a);
76static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *, IDI_SYNC_REQ *);
77
78void callback(ENTITY *);
79
80static void control_rc(PLCI *, byte, byte, byte, byte, byte);
81static void data_rc(PLCI *, byte);
82static void data_ack(PLCI *, byte);
83static void sig_ind(PLCI *);
84static void SendInfo(PLCI *, dword, byte **, byte);
85static void SendSetupInfo(APPL *, PLCI *, dword, byte **, byte);
86static void SendSSExtInd(APPL *, PLCI *plci, dword Id, byte **parms);
87
88static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms);
89
90static void nl_ind(PLCI *);
91
92static byte connect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
93static byte connect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
94static byte connect_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
95static byte disconnect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
96static byte disconnect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
97static byte listen_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
98static byte info_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
99static byte info_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
100static byte alert_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
101static byte facility_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
102static byte facility_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
103static byte connect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
104static byte connect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
105static byte connect_b3_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
106static byte disconnect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
107static byte disconnect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
108static byte data_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
109static byte data_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
110static byte reset_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
111static byte reset_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
112static byte connect_b3_t90_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
113static byte select_b_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
114static byte manufacturer_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
115static byte manufacturer_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
116
117static word get_plci(DIVA_CAPI_ADAPTER *);
118static void add_p(PLCI *, byte, byte *);
119static void add_s(PLCI *plci, byte code, API_PARSE *p);
120static void add_ss(PLCI *plci, byte code, API_PARSE *p);
121static void add_ie(PLCI *plci, byte code, byte *p, word p_length);
122static void add_d(PLCI *, word, byte *);
123static void add_ai(PLCI *, API_PARSE *);
124static word add_b1(PLCI *, API_PARSE *, word, word);
125static word add_b23(PLCI *, API_PARSE *);
126static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms);
127static void sig_req(PLCI *, byte, byte);
128static void nl_req_ncci(PLCI *, byte, byte);
129static void send_req(PLCI *);
130static void send_data(PLCI *);
131static word plci_remove_check(PLCI *);
132static void listen_check(DIVA_CAPI_ADAPTER *);
133static byte AddInfo(byte **, byte **, byte *, byte *);
134static byte getChannel(API_PARSE *);
135static void IndParse(PLCI *, const word *, byte **, byte);
136static byte ie_compare(byte *, byte *);
137static word find_cip(DIVA_CAPI_ADAPTER *, byte *, byte *);
138static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *, word);
139
140/*
141 XON protocol helpers
142*/
143static void channel_flow_control_remove(PLCI *plci);
144static void channel_x_off(PLCI *plci, byte ch, byte flag);
145static void channel_x_on(PLCI *plci, byte ch);
146static void channel_request_xon(PLCI *plci, byte ch);
147static void channel_xmit_xon(PLCI *plci);
148static int channel_can_xon(PLCI *plci, byte ch);
149static void channel_xmit_extended_xon(PLCI *plci);
150
151static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type, dword info_mask, byte setupParse);
152static word AdvCodecSupport(DIVA_CAPI_ADAPTER *, PLCI *, APPL *, byte);
153static void CodecIdCheck(DIVA_CAPI_ADAPTER *, PLCI *);
154static void SetVoiceChannel(PLCI *, byte *, DIVA_CAPI_ADAPTER *);
155static void VoiceChannelOff(PLCI *plci);
156static void adv_voice_write_coefs(PLCI *plci, word write_command);
157static void adv_voice_clear_config(PLCI *plci);
158
159static word get_b1_facilities(PLCI *plci, byte b1_resource);
160static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities);
161static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities);
162static word adjust_b_process(dword Id, PLCI *plci, byte Rc);
163static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command);
164static void adjust_b_restore(dword Id, PLCI *plci, byte Rc);
165static void reset_b3_command(dword Id, PLCI *plci, byte Rc);
166static void select_b_command(dword Id, PLCI *plci, byte Rc);
167static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc);
168static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc);
169static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc);
170static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc);
171static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc);
172static void hold_save_command(dword Id, PLCI *plci, byte Rc);
173static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc);
174static void init_b1_config(PLCI *plci);
175static void clear_b1_config(PLCI *plci);
176
177static void dtmf_command(dword Id, PLCI *plci, byte Rc);
178static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
179static void dtmf_confirmation(dword Id, PLCI *plci);
180static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length);
181static void dtmf_parameter_write(PLCI *plci);
182
183
184static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id);
185static void mixer_set_bchannel_id(PLCI *plci, byte *chi);
186static void mixer_clear_config(PLCI *plci);
187static void mixer_notify_update(PLCI *plci, byte others);
188static void mixer_command(dword Id, PLCI *plci, byte Rc);
189static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
190static void mixer_indication_coefs_set(dword Id, PLCI *plci);
191static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length);
192static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length);
193static void mixer_remove(PLCI *plci);
194
195
196static void ec_command(dword Id, PLCI *plci, byte Rc);
197static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
198static void ec_indication(dword Id, PLCI *plci, byte *msg, word length);
199
200
201static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc);
202static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc);
203
204
205static int diva_get_dma_descriptor(PLCI *plci, dword *dma_magic);
206static void diva_free_dma_descriptor(PLCI *plci, int nr);
207
208/*------------------------------------------------------------------*/
209/* external function prototypes */
210/*------------------------------------------------------------------*/
211
212extern byte MapController(byte);
213extern byte UnMapController(byte);
214#define MapId(Id)(((Id) & 0xffffff00L) | MapController((byte)(Id)))
215#define UnMapId(Id)(((Id) & 0xffffff00L) | UnMapController((byte)(Id)))
216
217void sendf(APPL *, word, dword, word, byte *, ...);
218void *TransmitBufferSet(APPL *appl, dword ref);
219void *TransmitBufferGet(APPL *appl, void *p);
220void TransmitBufferFree(APPL *appl, void *p);
221void *ReceiveBufferGet(APPL *appl, int Num);
222
223int fax_head_line_time(char *buffer);
224
225
226/*------------------------------------------------------------------*/
227/* Global data definitions */
228/*------------------------------------------------------------------*/
229extern byte max_adapter;
230extern byte max_appl;
231extern DIVA_CAPI_ADAPTER *adapter;
232extern APPL *application;
233
234
235
236
237
238
239
240static byte remove_started = false;
241static PLCI dummy_plci;
242
243
244static struct _ftable {
245 word command;
246 byte *format;
247 byte (*function)(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
248} ftable[] = {
249 {_DATA_B3_R, "dwww", data_b3_req},
250 {_DATA_B3_I | RESPONSE, "w", data_b3_res},
251 {_INFO_R, "ss", info_req},
252 {_INFO_I | RESPONSE, "", info_res},
253 {_CONNECT_R, "wsssssssss", connect_req},
254 {_CONNECT_I | RESPONSE, "wsssss", connect_res},
255 {_CONNECT_ACTIVE_I | RESPONSE, "", connect_a_res},
256 {_DISCONNECT_R, "s", disconnect_req},
257 {_DISCONNECT_I | RESPONSE, "", disconnect_res},
258 {_LISTEN_R, "dddss", listen_req},
259 {_ALERT_R, "s", alert_req},
260 {_FACILITY_R, "ws", facility_req},
261 {_FACILITY_I | RESPONSE, "ws", facility_res},
262 {_CONNECT_B3_R, "s", connect_b3_req},
263 {_CONNECT_B3_I | RESPONSE, "ws", connect_b3_res},
264 {_CONNECT_B3_ACTIVE_I | RESPONSE, "", connect_b3_a_res},
265 {_DISCONNECT_B3_R, "s", disconnect_b3_req},
266 {_DISCONNECT_B3_I | RESPONSE, "", disconnect_b3_res},
267 {_RESET_B3_R, "s", reset_b3_req},
268 {_RESET_B3_I | RESPONSE, "", reset_b3_res},
269 {_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "ws", connect_b3_t90_a_res},
270 {_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "", connect_b3_t90_a_res},
271 {_SELECT_B_REQ, "s", select_b_req},
272 {_MANUFACTURER_R, "dws", manufacturer_req},
273 {_MANUFACTURER_I | RESPONSE, "dws", manufacturer_res},
274 {_MANUFACTURER_I | RESPONSE, "", manufacturer_res}
275};
276
277static byte *cip_bc[29][2] = {
278 { "", "" }, /* 0 */
279 { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 1 */
280 { "\x02\x88\x90", "\x02\x88\x90" }, /* 2 */
281 { "\x02\x89\x90", "\x02\x89\x90" }, /* 3 */
282 { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 4 */
283 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 5 */
284 { "\x02\x98\x90", "\x02\x98\x90" }, /* 6 */
285 { "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */
286 { "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */
287 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 9 */
288 { "", "" }, /* 10 */
289 { "", "" }, /* 11 */
290 { "", "" }, /* 12 */
291 { "", "" }, /* 13 */
292 { "", "" }, /* 14 */
293 { "", "" }, /* 15 */
294
295 { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 16 */
296 { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 17 */
297 { "\x02\x88\x90", "\x02\x88\x90" }, /* 18 */
298 { "\x02\x88\x90", "\x02\x88\x90" }, /* 19 */
299 { "\x02\x88\x90", "\x02\x88\x90" }, /* 20 */
300 { "\x02\x88\x90", "\x02\x88\x90" }, /* 21 */
301 { "\x02\x88\x90", "\x02\x88\x90" }, /* 22 */
302 { "\x02\x88\x90", "\x02\x88\x90" }, /* 23 */
303 { "\x02\x88\x90", "\x02\x88\x90" }, /* 24 */
304 { "\x02\x88\x90", "\x02\x88\x90" }, /* 25 */
305 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 26 */
306 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 27 */
307 { "\x02\x88\x90", "\x02\x88\x90" } /* 28 */
308};
309
310static byte *cip_hlc[29] = {
311 "", /* 0 */
312 "", /* 1 */
313 "", /* 2 */
314 "", /* 3 */
315 "", /* 4 */
316 "", /* 5 */
317 "", /* 6 */
318 "", /* 7 */
319 "", /* 8 */
320 "", /* 9 */
321 "", /* 10 */
322 "", /* 11 */
323 "", /* 12 */
324 "", /* 13 */
325 "", /* 14 */
326 "", /* 15 */
327
328 "\x02\x91\x81", /* 16 */
329 "\x02\x91\x84", /* 17 */
330 "\x02\x91\xa1", /* 18 */
331 "\x02\x91\xa4", /* 19 */
332 "\x02\x91\xa8", /* 20 */
333 "\x02\x91\xb1", /* 21 */
334 "\x02\x91\xb2", /* 22 */
335 "\x02\x91\xb5", /* 23 */
336 "\x02\x91\xb8", /* 24 */
337 "\x02\x91\xc1", /* 25 */
338 "\x02\x91\x81", /* 26 */
339 "\x03\x91\xe0\x01", /* 27 */
340 "\x03\x91\xe0\x02" /* 28 */
341};
342
343/*------------------------------------------------------------------*/
344
345#define V120_HEADER_LENGTH 1
346#define V120_HEADER_EXTEND_BIT 0x80
347#define V120_HEADER_BREAK_BIT 0x40
348#define V120_HEADER_C1_BIT 0x04
349#define V120_HEADER_C2_BIT 0x08
350#define V120_HEADER_FLUSH_COND (V120_HEADER_BREAK_BIT | V120_HEADER_C1_BIT | V120_HEADER_C2_BIT)
351
352static byte v120_default_header[] =
353{
354
355 0x83 /* Ext, BR , res, res, C2 , C1 , B , F */
356
357};
358
359static byte v120_break_header[] =
360{
361
362 0xc3 | V120_HEADER_BREAK_BIT /* Ext, BR , res, res, C2 , C1 , B , F */
363
364};
365
366
367/*------------------------------------------------------------------*/
368/* API_PUT function */
369/*------------------------------------------------------------------*/
370
371word api_put(APPL *appl, CAPI_MSG *msg)
372{
373 word i, j, k, l, n;
374 word ret;
375 byte c;
376 byte controller;
377 DIVA_CAPI_ADAPTER *a;
378 PLCI *plci;
379 NCCI *ncci_ptr;
380 word ncci;
381 CAPI_MSG *m;
382 API_PARSE msg_parms[MAX_MSG_PARMS + 1];
383
384 if (msg->header.length < sizeof(msg->header) ||
385 msg->header.length > MAX_MSG_SIZE) {
386 dbug(1, dprintf("bad len"));
387 return _BAD_MSG;
388 }
389
390 controller = (byte)((msg->header.controller & 0x7f) - 1);
391
392 /* controller starts with 0 up to (max_adapter - 1) */
393 if (controller >= max_adapter)
394 {
395 dbug(1, dprintf("invalid ctrl"));
396 return _BAD_MSG;
397 }
398
399 a = &adapter[controller];
400 plci = NULL;
401 if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled)
402 {
403 dbug(1, dprintf("plci=%x", msg->header.plci));
404 plci = &a->plci[msg->header.plci - 1];
405 ncci = GET_WORD(&msg->header.ncci);
406 if (plci->Id
407 && (plci->appl
408 || (plci->State == INC_CON_PENDING)
409 || (plci->State == INC_CON_ALERT)
410 || (msg->header.command == (_DISCONNECT_I | RESPONSE)))
411 && ((ncci == 0)
412 || (msg->header.command == (_DISCONNECT_B3_I | RESPONSE))
413 || ((ncci < MAX_NCCI + 1) && (a->ncci_plci[ncci] == plci->Id))))
414 {
415 i = plci->msg_in_read_pos;
416 j = plci->msg_in_write_pos;
417 if (j >= i)
418 {
419 if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE)
420 i += MSG_IN_QUEUE_SIZE - j;
421 else
422 j = 0;
423 }
424 else
425 {
426
427 n = (((CAPI_MSG *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc;
428
429 if (i > MSG_IN_QUEUE_SIZE - n)
430 i = MSG_IN_QUEUE_SIZE - n + 1;
431 i -= j;
432 }
433
434 if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc))
435
436 {
437 dbug(0, dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d",
438 msg->header.length, plci->msg_in_write_pos,
439 plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));
440
441 return _QUEUE_FULL;
442 }
443 c = false;
444 if ((((byte *) msg) < ((byte *)(plci->msg_in_queue)))
445 || (((byte *) msg) >= ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
446 {
447 if (plci->msg_in_write_pos != plci->msg_in_read_pos)
448 c = true;
449 }
450 if (msg->header.command == _DATA_B3_R)
451 {
452 if (msg->header.length < 20)
453 {
454 dbug(1, dprintf("DATA_B3 REQ wrong length %d", msg->header.length));
455 return _BAD_MSG;
456 }
457 ncci_ptr = &(a->ncci[ncci]);
458 n = ncci_ptr->data_pending;
459 l = ncci_ptr->data_ack_pending;
460 k = plci->msg_in_read_pos;
461 while (k != plci->msg_in_write_pos)
462 {
463 if (k == plci->msg_in_wrap_pos)
464 k = 0;
465 if ((((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.command == _DATA_B3_R)
466 && (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.ncci == ncci))
467 {
468 n++;
469 if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004)
470 l++;
471 }
472
473 k += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.length +
474 MSG_IN_OVERHEAD + 3) & 0xfffc;
475
476 }
477 if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK))
478 {
479 dbug(0, dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d",
480 ncci_ptr->data_pending, n, ncci_ptr->data_ack_pending, l));
481
482 return _QUEUE_FULL;
483 }
484 if (plci->req_in || plci->internal_command)
485 {
486 if ((((byte *) msg) >= ((byte *)(plci->msg_in_queue)))
487 && (((byte *) msg) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
488 {
489 dbug(0, dprintf("Q-FULL3(requeue)"));
490
491 return _QUEUE_FULL;
492 }
493 c = true;
494 }
495 }
496 else
497 {
498 if (plci->req_in || plci->internal_command)
499 c = true;
500 else
501 {
502 plci->command = msg->header.command;
503 plci->number = msg->header.number;
504 }
505 }
506 if (c)
507 {
508 dbug(1, dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d",
509 msg->header.command, plci->req_in, plci->internal_command,
510 msg->header.length, plci->msg_in_write_pos,
511 plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));
512 if (j == 0)
513 plci->msg_in_wrap_pos = plci->msg_in_write_pos;
514 m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]);
515 for (i = 0; i < msg->header.length; i++)
516 ((byte *)(plci->msg_in_queue))[j++] = ((byte *) msg)[i];
517 if (m->header.command == _DATA_B3_R)
518 {
519
520 m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet(appl, m->info.data_b3_req.Data));
521
522 }
523
524 j = (j + 3) & 0xfffc;
525
526 *((APPL **)(&((byte *)(plci->msg_in_queue))[j])) = appl;
527 plci->msg_in_write_pos = j + MSG_IN_OVERHEAD;
528 return 0;
529 }
530 }
531 else
532 {
533 plci = NULL;
534 }
535 }
536 dbug(1, dprintf("com=%x", msg->header.command));
537
538 for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0;
539 for (i = 0, ret = _BAD_MSG; i < ARRAY_SIZE(ftable); i++) {
540
541 if (ftable[i].command == msg->header.command) {
542 /* break loop if the message is correct, otherwise continue scan */
543 /* (for example: CONNECT_B3_T90_ACT_RES has two specifications) */
544 if (!api_parse(msg->info.b, (word)(msg->header.length - 12), ftable[i].format, msg_parms)) {
545 ret = 0;
546 break;
547 }
548 for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0;
549 }
550 }
551 if (ret) {
552 dbug(1, dprintf("BAD_MSG"));
553 if (plci) plci->command = 0;
554 return ret;
555 }
556
557
558 c = ftable[i].function(GET_DWORD(&msg->header.controller),
559 msg->header.number,
560 a,
561 plci,
562 appl,
563 msg_parms);
564
565 channel_xmit_extended_xon(plci);
566
567 if (c == 1) send_req(plci);
568 if (c == 2 && plci) plci->req_in = plci->req_in_start = plci->req_out = 0;
569 if (plci && !plci->req_in) plci->command = 0;
570 return 0;
571}
572
573
574/*------------------------------------------------------------------*/
575/* api_parse function, check the format of api messages */
576/*------------------------------------------------------------------*/
577
578static word api_parse(byte *msg, word length, byte *format, API_PARSE *parms)
579{
580 word i;
581 word p;
582
583 for (i = 0, p = 0; format[i]; i++) {
584 if (parms)
585 {
586 parms[i].info = &msg[p];
587 }
588 switch (format[i]) {
589 case 'b':
590 p += 1;
591 break;
592 case 'w':
593 p += 2;
594 break;
595 case 'd':
596 p += 4;
597 break;
598 case 's':
599 if (msg[p] == 0xff) {
600 parms[i].info += 2;
601 parms[i].length = msg[p + 1] + (msg[p + 2] << 8);
602 p += (parms[i].length + 3);
603 }
604 else {
605 parms[i].length = msg[p];
606 p += (parms[i].length + 1);
607 }
608 break;
609 }
610
611 if (p > length) return true;
612 }
613 if (parms) parms[i].info = NULL;
614 return false;
615}
616
617static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out)
618{
619 word i, j, n = 0;
620 byte *p;
621
622 p = out->info;
623 for (i = 0; format[i] != '\0'; i++)
624 {
625 out->parms[i].info = p;
626 out->parms[i].length = in[i].length;
627 switch (format[i])
628 {
629 case 'b':
630 n = 1;
631 break;
632 case 'w':
633 n = 2;
634 break;
635 case 'd':
636 n = 4;
637 break;
638 case 's':
639 n = in[i].length + 1;
640 break;
641 }
642 for (j = 0; j < n; j++)
643 *(p++) = in[i].info[j];
644 }
645 out->parms[i].info = NULL;
646 out->parms[i].length = 0;
647}
648
649static void api_load_msg(API_SAVE *in, API_PARSE *out)
650{
651 word i;
652
653 i = 0;
654 do
655 {
656 out[i].info = in->parms[i].info;
657 out[i].length = in->parms[i].length;
658 } while (in->parms[i++].info);
659}
660
661
662/*------------------------------------------------------------------*/
663/* CAPI remove function */
664/*------------------------------------------------------------------*/
665
666word api_remove_start(void)
667{
668 word i;
669 word j;
670
671 if (!remove_started) {
672 remove_started = true;
673 for (i = 0; i < max_adapter; i++) {
674 if (adapter[i].request) {
675 for (j = 0; j < adapter[i].max_plci; j++) {
676 if (adapter[i].plci[j].Sig.Id) plci_remove(&adapter[i].plci[j]);
677 }
678 }
679 }
680 return 1;
681 }
682 else {
683 for (i = 0; i < max_adapter; i++) {
684 if (adapter[i].request) {
685 for (j = 0; j < adapter[i].max_plci; j++) {
686 if (adapter[i].plci[j].Sig.Id) return 1;
687 }
688 }
689 }
690 }
691 api_remove_complete();
692 return 0;
693}
694
695
696/*------------------------------------------------------------------*/
697/* internal command queue */
698/*------------------------------------------------------------------*/
699
700static void init_internal_command_queue(PLCI *plci)
701{
702 word i;
703
704 dbug(1, dprintf("%s,%d: init_internal_command_queue",
705 (char *)(FILE_), __LINE__));
706
707 plci->internal_command = 0;
708 for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++)
709 plci->internal_command_queue[i] = NULL;
710}
711
712
713static void start_internal_command(dword Id, PLCI *plci, t_std_internal_command command_function)
714{
715 word i;
716
717 dbug(1, dprintf("[%06lx] %s,%d: start_internal_command",
718 UnMapId(Id), (char *)(FILE_), __LINE__));
719
720 if (plci->internal_command == 0)
721 {
722 plci->internal_command_queue[0] = command_function;
723 (*command_function)(Id, plci, OK);
724 }
725 else
726 {
727 i = 1;
728 while (plci->internal_command_queue[i] != NULL)
729 i++;
730 plci->internal_command_queue[i] = command_function;
731 }
732}
733
734
735static void next_internal_command(dword Id, PLCI *plci)
736{
737 word i;
738
739 dbug(1, dprintf("[%06lx] %s,%d: next_internal_command",
740 UnMapId(Id), (char *)(FILE_), __LINE__));
741
742 plci->internal_command = 0;
743 plci->internal_command_queue[0] = NULL;
744 while (plci->internal_command_queue[1] != NULL)
745 {
746 for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS - 1; i++)
747 plci->internal_command_queue[i] = plci->internal_command_queue[i + 1];
748 plci->internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS - 1] = NULL;
749 (*(plci->internal_command_queue[0]))(Id, plci, OK);
750 if (plci->internal_command != 0)
751 return;
752 plci->internal_command_queue[0] = NULL;
753 }
754}
755
756
757/*------------------------------------------------------------------*/
758/* NCCI allocate/remove function */
759/*------------------------------------------------------------------*/
760
761static dword ncci_mapping_bug = 0;
762
763static word get_ncci(PLCI *plci, byte ch, word force_ncci)
764{
765 DIVA_CAPI_ADAPTER *a;
766 word ncci, i, j, k;
767
768 a = plci->adapter;
769 if (!ch || a->ch_ncci[ch])
770 {
771 ncci_mapping_bug++;
772 dbug(1, dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x",
773 ncci_mapping_bug, ch, force_ncci, a->ncci_ch[a->ch_ncci[ch]], a->ch_ncci[ch]));
774 ncci = ch;
775 }
776 else
777 {
778 if (force_ncci)
779 ncci = force_ncci;
780 else
781 {
782 if ((ch < MAX_NCCI + 1) && !a->ncci_ch[ch])
783 ncci = ch;
784 else
785 {
786 ncci = 1;
787 while ((ncci < MAX_NCCI + 1) && a->ncci_ch[ncci])
788 ncci++;
789 if (ncci == MAX_NCCI + 1)
790 {
791 ncci_mapping_bug++;
792 i = 1;
793 do
794 {
795 j = 1;
796 while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i))
797 j++;
798 k = j;
799 if (j < MAX_NCCI + 1)
800 {
801 do
802 {
803 j++;
804 } while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i));
805 }
806 } while ((i < MAX_NL_CHANNEL + 1) && (j < MAX_NCCI + 1));
807 if (i < MAX_NL_CHANNEL + 1)
808 {
809 dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x",
810 ncci_mapping_bug, ch, force_ncci, i, k, j));
811 }
812 else
813 {
814 dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x",
815 ncci_mapping_bug, ch, force_ncci));
816 }
817 ncci = ch;
818 }
819 }
820 a->ncci_plci[ncci] = plci->Id;
821 a->ncci_state[ncci] = IDLE;
822 if (!plci->ncci_ring_list)
823 plci->ncci_ring_list = ncci;
824 else
825 a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list];
826 a->ncci_next[plci->ncci_ring_list] = (byte) ncci;
827 }
828 a->ncci_ch[ncci] = ch;
829 a->ch_ncci[ch] = (byte) ncci;
830 dbug(1, dprintf("NCCI mapping established %ld %02x %02x %02x-%02x",
831 ncci_mapping_bug, ch, force_ncci, ch, ncci));
832 }
833 return (ncci);
834}
835
836
837static void ncci_free_receive_buffers(PLCI *plci, word ncci)
838{
839 DIVA_CAPI_ADAPTER *a;
840 APPL *appl;
841 word i, ncci_code;
842 dword Id;
843
844 a = plci->adapter;
845 Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
846 if (ncci)
847 {
848 if (a->ncci_plci[ncci] == plci->Id)
849 {
850 if (!plci->appl)
851 {
852 ncci_mapping_bug++;
853 dbug(1, dprintf("NCCI mapping appl expected %ld %08lx",
854 ncci_mapping_bug, Id));
855 }
856 else
857 {
858 appl = plci->appl;
859 ncci_code = ncci | (((word) a->Id) << 8);
860 for (i = 0; i < appl->MaxBuffer; i++)
861 {
862 if ((appl->DataNCCI[i] == ncci_code)
863 && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
864 {
865 appl->DataNCCI[i] = 0;
866 }
867 }
868 }
869 }
870 }
871 else
872 {
873 for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
874 {
875 if (a->ncci_plci[ncci] == plci->Id)
876 {
877 if (!plci->appl)
878 {
879 ncci_mapping_bug++;
880 dbug(1, dprintf("NCCI mapping no appl %ld %08lx",
881 ncci_mapping_bug, Id));
882 }
883 else
884 {
885 appl = plci->appl;
886 ncci_code = ncci | (((word) a->Id) << 8);
887 for (i = 0; i < appl->MaxBuffer; i++)
888 {
889 if ((appl->DataNCCI[i] == ncci_code)
890 && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
891 {
892 appl->DataNCCI[i] = 0;
893 }
894 }
895 }
896 }
897 }
898 }
899}
900
901
902static void cleanup_ncci_data(PLCI *plci, word ncci)
903{
904 NCCI *ncci_ptr;
905
906 if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id))
907 {
908 ncci_ptr = &(plci->adapter->ncci[ncci]);
909 if (plci->appl)
910 {
911 while (ncci_ptr->data_pending != 0)
912 {
913 if (!plci->data_sent || (ncci_ptr->DBuffer[ncci_ptr->data_out].P != plci->data_sent_ptr))
914 TransmitBufferFree(plci->appl, ncci_ptr->DBuffer[ncci_ptr->data_out].P);
915 (ncci_ptr->data_out)++;
916 if (ncci_ptr->data_out == MAX_DATA_B3)
917 ncci_ptr->data_out = 0;
918 (ncci_ptr->data_pending)--;
919 }
920 }
921 ncci_ptr->data_out = 0;
922 ncci_ptr->data_pending = 0;
923 ncci_ptr->data_ack_out = 0;
924 ncci_ptr->data_ack_pending = 0;
925 }
926}
927
928
929static void ncci_remove(PLCI *plci, word ncci, byte preserve_ncci)
930{
931 DIVA_CAPI_ADAPTER *a;
932 dword Id;
933 word i;
934
935 a = plci->adapter;
936 Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
937 if (!preserve_ncci)
938 ncci_free_receive_buffers(plci, ncci);
939 if (ncci)
940 {
941 if (a->ncci_plci[ncci] != plci->Id)
942 {
943 ncci_mapping_bug++;
944 dbug(1, dprintf("NCCI mapping doesn't exist %ld %08lx %02x",
945 ncci_mapping_bug, Id, preserve_ncci));
946 }
947 else
948 {
949 cleanup_ncci_data(plci, ncci);
950 dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
951 ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
952 a->ch_ncci[a->ncci_ch[ncci]] = 0;
953 if (!preserve_ncci)
954 {
955 a->ncci_ch[ncci] = 0;
956 a->ncci_plci[ncci] = 0;
957 a->ncci_state[ncci] = IDLE;
958 i = plci->ncci_ring_list;
959 while ((i != 0) && (a->ncci_next[i] != plci->ncci_ring_list) && (a->ncci_next[i] != ncci))
960 i = a->ncci_next[i];
961 if ((i != 0) && (a->ncci_next[i] == ncci))
962 {
963 if (i == ncci)
964 plci->ncci_ring_list = 0;
965 else if (plci->ncci_ring_list == ncci)
966 plci->ncci_ring_list = i;
967 a->ncci_next[i] = a->ncci_next[ncci];
968 }
969 a->ncci_next[ncci] = 0;
970 }
971 }
972 }
973 else
974 {
975 for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
976 {
977 if (a->ncci_plci[ncci] == plci->Id)
978 {
979 cleanup_ncci_data(plci, ncci);
980 dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
981 ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
982 a->ch_ncci[a->ncci_ch[ncci]] = 0;
983 if (!preserve_ncci)
984 {
985 a->ncci_ch[ncci] = 0;
986 a->ncci_plci[ncci] = 0;
987 a->ncci_state[ncci] = IDLE;
988 a->ncci_next[ncci] = 0;
989 }
990 }
991 }
992 if (!preserve_ncci)
993 plci->ncci_ring_list = 0;
994 }
995}
996
997
998/*------------------------------------------------------------------*/
999/* PLCI remove function */
1000/*------------------------------------------------------------------*/
1001
1002static void plci_free_msg_in_queue(PLCI *plci)
1003{
1004 word i;
1005
1006 if (plci->appl)
1007 {
1008 i = plci->msg_in_read_pos;
1009 while (i != plci->msg_in_write_pos)
1010 {
1011 if (i == plci->msg_in_wrap_pos)
1012 i = 0;
1013 if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R)
1014 {
1015
1016 TransmitBufferFree(plci->appl,
1017 (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
1018
1019 }
1020
1021 i += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.length +
1022 MSG_IN_OVERHEAD + 3) & 0xfffc;
1023
1024 }
1025 }
1026 plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
1027 plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
1028 plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
1029}
1030
1031
1032static void plci_remove(PLCI *plci)
1033{
1034
1035 if (!plci) {
1036 dbug(1, dprintf("plci_remove(no plci)"));
1037 return;
1038 }
1039 init_internal_command_queue(plci);
1040 dbug(1, dprintf("plci_remove(%x,tel=%x)", plci->Id, plci->tel));
1041 if (plci_remove_check(plci))
1042 {
1043 return;
1044 }
1045 if (plci->Sig.Id == 0xff)
1046 {
1047 dbug(1, dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id));
1048 if (plci->NL.Id && !plci->nl_remove_id)
1049 {
1050 nl_req_ncci(plci, REMOVE, 0);
1051 send_req(plci);
1052 }
1053 }
1054 else
1055 {
1056 if (!plci->sig_remove_id
1057 && (plci->Sig.Id
1058 || (plci->req_in != plci->req_out)
1059 || (plci->nl_req || plci->sig_req)))
1060 {
1061 sig_req(plci, HANGUP, 0);
1062 send_req(plci);
1063 }
1064 }
1065 ncci_remove(plci, 0, false);
1066 plci_free_msg_in_queue(plci);
1067
1068 plci->channels = 0;
1069 plci->appl = NULL;
1070 if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT))
1071 plci->State = OUTG_DIS_PENDING;
1072}
1073
1074/*------------------------------------------------------------------*/
1075/* translation function for each message */
1076/*------------------------------------------------------------------*/
1077
1078static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1079 PLCI *plci, APPL *appl, API_PARSE *parms)
1080{
1081 word ch;
1082 word i;
1083 word Info;
1084 byte LinkLayer;
1085 API_PARSE *ai;
1086 API_PARSE *bp;
1087 API_PARSE ai_parms[5];
1088 word channel = 0;
1089 dword ch_mask;
1090 byte m;
1091 static byte esc_chi[35] = {0x02, 0x18, 0x01};
1092 static byte lli[2] = {0x01, 0x00};
1093 byte noCh = 0;
1094 word dir = 0;
1095 byte *p_chi = "";
1096
1097 for (i = 0; i < 5; i++) ai_parms[i].length = 0;
1098
1099 dbug(1, dprintf("connect_req(%d)", parms->length));
1100 Info = _WRONG_IDENTIFIER;
1101 if (a)
1102 {
1103 if (a->adapter_disabled)
1104 {
1105 dbug(1, dprintf("adapter disabled"));
1106 Id = ((word)1 << 8) | a->Id;
1107 sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
1108 sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR);
1109 return false;
1110 }
1111 Info = _OUT_OF_PLCI;
1112 if ((i = get_plci(a)))
1113 {
1114 Info = 0;
1115 plci = &a->plci[i - 1];
1116 plci->appl = appl;
1117 plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
1118 /* check 'external controller' bit for codec support */
1119 if (Id & EXT_CONTROLLER)
1120 {
1121 if (AdvCodecSupport(a, plci, appl, 0))
1122 {
1123 plci->Id = 0;
1124 sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
1125 return 2;
1126 }
1127 }
1128 ai = &parms[9];
1129 bp = &parms[5];
1130 ch = 0;
1131 if (bp->length)LinkLayer = bp->info[3];
1132 else LinkLayer = 0;
1133 if (ai->length)
1134 {
1135 ch = 0xffff;
1136 if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
1137 {
1138 ch = 0;
1139 if (ai_parms[0].length)
1140 {
1141 ch = GET_WORD(ai_parms[0].info + 1);
1142 if (ch > 4) ch = 0; /* safety -> ignore ChannelID */
1143 if (ch == 4) /* explizit CHI in message */
1144 {
1145 /* check length of B-CH struct */
1146 if ((ai_parms[0].info)[3] >= 1)
1147 {
1148 if ((ai_parms[0].info)[4] == CHI)
1149 {
1150 p_chi = &((ai_parms[0].info)[5]);
1151 }
1152 else
1153 {
1154 p_chi = &((ai_parms[0].info)[3]);
1155 }
1156 if (p_chi[0] > 35) /* check length of channel ID */
1157 {
1158 Info = _WRONG_MESSAGE_FORMAT;
1159 }
1160 }
1161 else Info = _WRONG_MESSAGE_FORMAT;
1162 }
1163
1164 if (ch == 3 && ai_parms[0].length >= 7 && ai_parms[0].length <= 36)
1165 {
1166 dir = GET_WORD(ai_parms[0].info + 3);
1167 ch_mask = 0;
1168 m = 0x3f;
1169 for (i = 0; i + 5 <= ai_parms[0].length; i++)
1170 {
1171 if (ai_parms[0].info[i + 5] != 0)
1172 {
1173 if ((ai_parms[0].info[i + 5] | m) != 0xff)
1174 Info = _WRONG_MESSAGE_FORMAT;
1175 else
1176 {
1177 if (ch_mask == 0)
1178 channel = i;
1179 ch_mask |= 1L << i;
1180 }
1181 }
1182 m = 0;
1183 }
1184 if (ch_mask == 0)
1185 Info = _WRONG_MESSAGE_FORMAT;
1186 if (!Info)
1187 {
1188 if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel))))
1189 {
1190 esc_chi[0] = (byte)(ai_parms[0].length - 2);
1191 for (i = 0; i + 5 <= ai_parms[0].length; i++)
1192 esc_chi[i + 3] = ai_parms[0].info[i + 5];
1193 }
1194 else
1195 esc_chi[0] = 2;
1196 esc_chi[2] = (byte)channel;
1197 plci->b_channel = (byte)channel; /* not correct for ETSI ch 17..31 */
1198 add_p(plci, LLI, lli);
1199 add_p(plci, ESC, esc_chi);
1200 plci->State = LOCAL_CONNECT;
1201 if (!dir) plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; /* dir 0=DTE, 1=DCE */
1202 }
1203 }
1204 }
1205 }
1206 else Info = _WRONG_MESSAGE_FORMAT;
1207 }
1208
1209 dbug(1, dprintf("ch=%x,dir=%x,p_ch=%d", ch, dir, channel));
1210 plci->command = _CONNECT_R;
1211 plci->number = Number;
1212 /* x.31 or D-ch free SAPI in LinkLayer? */
1213 if (ch == 1 && LinkLayer != 3 && LinkLayer != 12) noCh = true;
1214 if ((ch == 0 || ch == 2 || noCh || ch == 3 || ch == 4) && !Info)
1215 {
1216 /* B-channel used for B3 connections (ch==0), or no B channel */
1217 /* is used (ch==2) or perm. connection (3) is used do a CALL */
1218 if (noCh) Info = add_b1(plci, &parms[5], 2, 0); /* no resource */
1219 else Info = add_b1(plci, &parms[5], ch, 0);
1220 add_s(plci, OAD, &parms[2]);
1221 add_s(plci, OSA, &parms[4]);
1222 add_s(plci, BC, &parms[6]);
1223 add_s(plci, LLC, &parms[7]);
1224 add_s(plci, HLC, &parms[8]);
1225 if (a->Info_Mask[appl->Id - 1] & 0x200)
1226 {
1227 /* early B3 connect (CIP mask bit 9) no release after a disc */
1228 add_p(plci, LLI, "\x01\x01");
1229 }
1230 if (GET_WORD(parms[0].info) < 29) {
1231 add_p(plci, BC, cip_bc[GET_WORD(parms[0].info)][a->u_law]);
1232 add_p(plci, HLC, cip_hlc[GET_WORD(parms[0].info)]);
1233 }
1234 add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
1235 sig_req(plci, ASSIGN, DSIG_ID);
1236 }
1237 else if (ch == 1) {
1238
1239 /* D-Channel used for B3 connections */
1240 plci->Sig.Id = 0xff;
1241 Info = 0;
1242 }
1243
1244 if (!Info && ch != 2 && !noCh) {
1245 Info = add_b23(plci, &parms[5]);
1246 if (!Info) {
1247 if (!(plci->tel && !plci->adv_nl))nl_req_ncci(plci, ASSIGN, 0);
1248 }
1249 }
1250
1251 if (!Info)
1252 {
1253 if (ch == 0 || ch == 2 || ch == 3 || noCh || ch == 4)
1254 {
1255 if (plci->spoofed_msg == SPOOFING_REQUIRED)
1256 {
1257 api_save_msg(parms, "wsssssssss", &plci->saved_msg);
1258 plci->spoofed_msg = CALL_REQ;
1259 plci->internal_command = BLOCK_PLCI;
1260 plci->command = 0;
1261 dbug(1, dprintf("Spoof"));
1262 send_req(plci);
1263 return false;
1264 }
1265 if (ch == 4)add_p(plci, CHI, p_chi);
1266 add_s(plci, CPN, &parms[1]);
1267 add_s(plci, DSA, &parms[3]);
1268 if (noCh) add_p(plci, ESC, "\x02\x18\xfd"); /* D-channel, no B-L3 */
1269 add_ai(plci, &parms[9]);
1270 if (!dir)sig_req(plci, CALL_REQ, 0);
1271 else
1272 {
1273 plci->command = PERM_LIST_REQ;
1274 plci->appl = appl;
1275 sig_req(plci, LISTEN_REQ, 0);
1276 send_req(plci);
1277 return false;
1278 }
1279 }
1280 send_req(plci);
1281 return false;
1282 }
1283 plci->Id = 0;
1284 }
1285 }
1286 sendf(appl,
1287 _CONNECT_R | CONFIRM,
1288 Id,
1289 Number,
1290 "w", Info);
1291 return 2;
1292}
1293
1294static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1295 PLCI *plci, APPL *appl, API_PARSE *parms)
1296{
1297 word i, Info;
1298 word Reject;
1299 static byte cau_t[] = {0, 0, 0x90, 0x91, 0xac, 0x9d, 0x86, 0xd8, 0x9b};
1300 static byte esc_t[] = {0x03, 0x08, 0x00, 0x00};
1301 API_PARSE *ai;
1302 API_PARSE ai_parms[5];
1303 word ch = 0;
1304
1305 if (!plci) {
1306 dbug(1, dprintf("connect_res(no plci)"));
1307 return 0; /* no plci, no send */
1308 }
1309
1310 dbug(1, dprintf("connect_res(State=0x%x)", plci->State));
1311 for (i = 0; i < 5; i++) ai_parms[i].length = 0;
1312 ai = &parms[5];
1313 dbug(1, dprintf("ai->length=%d", ai->length));
1314
1315 if (ai->length)
1316 {
1317 if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
1318 {
1319 dbug(1, dprintf("ai_parms[0].length=%d/0x%x", ai_parms[0].length, GET_WORD(ai_parms[0].info + 1)));
1320 ch = 0;
1321 if (ai_parms[0].length)
1322 {
1323 ch = GET_WORD(ai_parms[0].info + 1);
1324 dbug(1, dprintf("BCH-I=0x%x", ch));
1325 }
1326 }
1327 }
1328
1329 if (plci->State == INC_CON_CONNECTED_ALERT)
1330 {
1331 dbug(1, dprintf("Connected Alert Call_Res"));
1332 if (a->Info_Mask[appl->Id - 1] & 0x200)
1333 {
1334 /* early B3 connect (CIP mask bit 9) no release after a disc */
1335 add_p(plci, LLI, "\x01\x01");
1336 }
1337 add_s(plci, CONN_NR, &parms[2]);
1338 add_s(plci, LLC, &parms[4]);
1339 add_ai(plci, &parms[5]);
1340 plci->State = INC_CON_ACCEPT;
1341 sig_req(plci, CALL_RES, 0);
1342 return 1;
1343 }
1344 else if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT) {
1345 __clear_bit(appl->Id - 1, plci->c_ind_mask_table);
1346 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
1347 Reject = GET_WORD(parms[0].info);
1348 dbug(1, dprintf("Reject=0x%x", Reject));
1349 if (Reject)
1350 {
1351 if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
1352 {
1353 if ((Reject & 0xff00) == 0x3400)
1354 {
1355 esc_t[2] = ((byte)(Reject & 0x00ff)) | 0x80;
1356 add_p(plci, ESC, esc_t);
1357 add_ai(plci, &parms[5]);
1358 sig_req(plci, REJECT, 0);
1359 }
1360 else if (Reject == 1 || Reject >= 9)
1361 {
1362 add_ai(plci, &parms[5]);
1363 sig_req(plci, HANGUP, 0);
1364 }
1365 else
1366 {
1367 esc_t[2] = cau_t[(Reject&0x000f)];
1368 add_p(plci, ESC, esc_t);
1369 add_ai(plci, &parms[5]);
1370 sig_req(plci, REJECT, 0);
1371 }
1372 plci->appl = appl;
1373 }
1374 else
1375 {
1376 sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
1377 }
1378 }
1379 else {
1380 plci->appl = appl;
1381 if (Id & EXT_CONTROLLER) {
1382 if (AdvCodecSupport(a, plci, appl, 0)) {
1383 dbug(1, dprintf("connect_res(error from AdvCodecSupport)"));
1384 sig_req(plci, HANGUP, 0);
1385 return 1;
1386 }
1387 if (plci->tel == ADV_VOICE && a->AdvCodecPLCI)
1388 {
1389 Info = add_b23(plci, &parms[1]);
1390 if (Info)
1391 {
1392 dbug(1, dprintf("connect_res(error from add_b23)"));
1393 sig_req(plci, HANGUP, 0);
1394 return 1;
1395 }
1396 if (plci->adv_nl)
1397 {
1398 nl_req_ncci(plci, ASSIGN, 0);
1399 }
1400 }
1401 }
1402 else
1403 {
1404 plci->tel = 0;
1405 if (ch != 2)
1406 {
1407 Info = add_b23(plci, &parms[1]);
1408 if (Info)
1409 {
1410 dbug(1, dprintf("connect_res(error from add_b23 2)"));
1411 sig_req(plci, HANGUP, 0);
1412 return 1;
1413 }
1414 }
1415 nl_req_ncci(plci, ASSIGN, 0);
1416 }
1417
1418 if (plci->spoofed_msg == SPOOFING_REQUIRED)
1419 {
1420 api_save_msg(parms, "wsssss", &plci->saved_msg);
1421 plci->spoofed_msg = CALL_RES;
1422 plci->internal_command = BLOCK_PLCI;
1423 plci->command = 0;
1424 dbug(1, dprintf("Spoof"));
1425 }
1426 else
1427 {
1428 add_b1(plci, &parms[1], ch, plci->B1_facilities);
1429 if (a->Info_Mask[appl->Id - 1] & 0x200)
1430 {
1431 /* early B3 connect (CIP mask bit 9) no release after a disc */
1432 add_p(plci, LLI, "\x01\x01");
1433 }
1434 add_s(plci, CONN_NR, &parms[2]);
1435 add_s(plci, LLC, &parms[4]);
1436 add_ai(plci, &parms[5]);
1437 plci->State = INC_CON_ACCEPT;
1438 sig_req(plci, CALL_RES, 0);
1439 }
1440
1441 for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
1442 sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
1443 }
1444 }
1445 return 1;
1446}
1447
1448static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1449 PLCI *plci, APPL *appl, API_PARSE *msg)
1450{
1451 dbug(1, dprintf("connect_a_res"));
1452 return false;
1453}
1454
1455static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1456 PLCI *plci, APPL *appl, API_PARSE *msg)
1457{
1458 word Info;
1459 word i;
1460
1461 dbug(1, dprintf("disconnect_req"));
1462
1463 Info = _WRONG_IDENTIFIER;
1464
1465 if (plci)
1466 {
1467 if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
1468 {
1469 __clear_bit(appl->Id - 1, plci->c_ind_mask_table);
1470 plci->appl = appl;
1471 for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
1472 sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
1473 plci->State = OUTG_DIS_PENDING;
1474 }
1475 if (plci->Sig.Id && plci->appl)
1476 {
1477 Info = 0;
1478 if (plci->Sig.Id != 0xff)
1479 {
1480 if (plci->State != INC_DIS_PENDING)
1481 {
1482 add_ai(plci, &msg[0]);
1483 sig_req(plci, HANGUP, 0);
1484 plci->State = OUTG_DIS_PENDING;
1485 return 1;
1486 }
1487 }
1488 else
1489 {
1490 if (plci->NL.Id && !plci->nl_remove_id)
1491 {
1492 mixer_remove(plci);
1493 nl_req_ncci(plci, REMOVE, 0);
1494 sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0);
1495 sendf(appl, _DISCONNECT_I, Id, 0, "w", 0);
1496 plci->State = INC_DIS_PENDING;
1497 }
1498 return 1;
1499 }
1500 }
1501 }
1502
1503 if (!appl) return false;
1504 sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", Info);
1505 return false;
1506}
1507
1508static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1509 PLCI *plci, APPL *appl, API_PARSE *msg)
1510{
1511 dbug(1, dprintf("disconnect_res"));
1512 if (plci)
1513 {
1514 /* clear ind mask bit, just in case of collsion of */
1515 /* DISCONNECT_IND and CONNECT_RES */
1516 __clear_bit(appl->Id - 1, plci->c_ind_mask_table);
1517 ncci_free_receive_buffers(plci, 0);
1518 if (plci_remove_check(plci))
1519 {
1520 return 0;
1521 }
1522 if (plci->State == INC_DIS_PENDING
1523 || plci->State == SUSPENDING) {
1524 if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL)) {
1525 if (plci->State != SUSPENDING) plci->State = IDLE;
1526 dbug(1, dprintf("chs=%d", plci->channels));
1527 if (!plci->channels) {
1528 plci_remove(plci);
1529 }
1530 }
1531 }
1532 }
1533 return 0;
1534}
1535
1536static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1537 PLCI *plci, APPL *appl, API_PARSE *parms)
1538{
1539 word Info;
1540 byte i;
1541
1542 dbug(1, dprintf("listen_req(Appl=0x%x)", appl->Id));
1543
1544 Info = _WRONG_IDENTIFIER;
1545 if (a) {
1546 Info = 0;
1547 a->Info_Mask[appl->Id - 1] = GET_DWORD(parms[0].info);
1548 a->CIP_Mask[appl->Id - 1] = GET_DWORD(parms[1].info);
1549 dbug(1, dprintf("CIP_MASK=0x%lx", GET_DWORD(parms[1].info)));
1550 if (a->Info_Mask[appl->Id - 1] & 0x200) { /* early B3 connect provides */
1551 a->Info_Mask[appl->Id - 1] |= 0x10; /* call progression infos */
1552 }
1553
1554 /* check if external controller listen and switch listen on or off*/
1555 if (Id&EXT_CONTROLLER && GET_DWORD(parms[1].info)) {
1556 if (a->profile.Global_Options & ON_BOARD_CODEC) {
1557 dummy_plci.State = IDLE;
1558 a->codec_listen[appl->Id - 1] = &dummy_plci;
1559 a->TelOAD[0] = (byte)(parms[3].length);
1560 for (i = 1; parms[3].length >= i && i < 22; i++) {
1561 a->TelOAD[i] = parms[3].info[i];
1562 }
1563 a->TelOAD[i] = 0;
1564 a->TelOSA[0] = (byte)(parms[4].length);
1565 for (i = 1; parms[4].length >= i && i < 22; i++) {
1566 a->TelOSA[i] = parms[4].info[i];
1567 }
1568 a->TelOSA[i] = 0;
1569 }
1570 else Info = 0x2002; /* wrong controller, codec not supported */
1571 }
1572 else{ /* clear listen */
1573 a->codec_listen[appl->Id - 1] = (PLCI *)0;
1574 }
1575 }
1576 sendf(appl,
1577 _LISTEN_R | CONFIRM,
1578 Id,
1579 Number,
1580 "w", Info);
1581
1582 if (a) listen_check(a);
1583 return false;
1584}
1585
1586static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1587 PLCI *plci, APPL *appl, API_PARSE *msg)
1588{
1589 word i;
1590 API_PARSE *ai;
1591 PLCI *rc_plci = NULL;
1592 API_PARSE ai_parms[5];
1593 word Info = 0;
1594
1595 dbug(1, dprintf("info_req"));
1596 for (i = 0; i < 5; i++) ai_parms[i].length = 0;
1597
1598 ai = &msg[1];
1599
1600 if (ai->length)
1601 {
1602 if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
1603 {
1604 dbug(1, dprintf("AddInfo wrong"));
1605 Info = _WRONG_MESSAGE_FORMAT;
1606 }
1607 }
1608 if (!a) Info = _WRONG_STATE;
1609
1610 if (!Info && plci)
1611 { /* no fac, with CPN, or KEY */
1612 rc_plci = plci;
1613 if (!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length))
1614 {
1615 /* overlap sending option */
1616 dbug(1, dprintf("OvlSnd"));
1617 add_s(plci, CPN, &msg[0]);
1618 add_s(plci, KEY, &ai_parms[1]);
1619 sig_req(plci, INFO_REQ, 0);
1620 send_req(plci);
1621 return false;
1622 }
1623
1624 if (plci->State && ai_parms[2].length)
1625 {
1626 /* User_Info option */
1627 dbug(1, dprintf("UUI"));
1628 add_s(plci, UUI, &ai_parms[2]);
1629 sig_req(plci, USER_DATA, 0);
1630 }
1631 else if (plci->State && ai_parms[3].length)
1632 {
1633 /* Facility option */
1634 dbug(1, dprintf("FAC"));
1635 add_s(plci, CPN, &msg[0]);
1636 add_ai(plci, &msg[1]);
1637 sig_req(plci, FACILITY_REQ, 0);
1638 }
1639 else
1640 {
1641 Info = _WRONG_STATE;
1642 }
1643 }
1644 else if ((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info)
1645 {
1646 /* NCR_Facility option -> send UUI and Keypad too */
1647 dbug(1, dprintf("NCR_FAC"));
1648 if ((i = get_plci(a)))
1649 {
1650 rc_plci = &a->plci[i - 1];
1651 appl->NullCREnable = true;
1652 rc_plci->internal_command = C_NCR_FAC_REQ;
1653 rc_plci->appl = appl;
1654 add_p(rc_plci, CAI, "\x01\x80");
1655 add_p(rc_plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
1656 sig_req(rc_plci, ASSIGN, DSIG_ID);
1657 send_req(rc_plci);
1658 }
1659 else
1660 {
1661 Info = _OUT_OF_PLCI;
1662 }
1663
1664 if (!Info)
1665 {
1666 add_s(rc_plci, CPN, &msg[0]);
1667 add_ai(rc_plci, &msg[1]);
1668 sig_req(rc_plci, NCR_FACILITY, 0);
1669 send_req(rc_plci);
1670 return false;
1671 /* for application controlled supplementary services */
1672 }
1673 }
1674
1675 if (!rc_plci)
1676 {
1677 Info = _WRONG_MESSAGE_FORMAT;
1678 }
1679
1680 if (!Info)
1681 {
1682 send_req(rc_plci);
1683 }
1684 else
1685 { /* appl is not assigned to a PLCI or error condition */
1686 dbug(1, dprintf("localInfoCon"));
1687 sendf(appl,
1688 _INFO_R | CONFIRM,
1689 Id,
1690 Number,
1691 "w", Info);
1692 }
1693 return false;
1694}
1695
1696static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1697 PLCI *plci, APPL *appl, API_PARSE *msg)
1698{
1699 dbug(1, dprintf("info_res"));
1700 return false;
1701}
1702
1703static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1704 PLCI *plci, APPL *appl, API_PARSE *msg)
1705{
1706 word Info;
1707 byte ret;
1708
1709 dbug(1, dprintf("alert_req"));
1710
1711 Info = _WRONG_IDENTIFIER;
1712 ret = false;
1713 if (plci) {
1714 Info = _ALERT_IGNORED;
1715 if (plci->State != INC_CON_ALERT) {
1716 Info = _WRONG_STATE;
1717 if (plci->State == INC_CON_PENDING) {
1718 Info = 0;
1719 plci->State = INC_CON_ALERT;
1720 add_ai(plci, &msg[0]);
1721 sig_req(plci, CALL_ALERT, 0);
1722 ret = 1;
1723 }
1724 }
1725 }
1726 sendf(appl,
1727 _ALERT_R | CONFIRM,
1728 Id,
1729 Number,
1730 "w", Info);
1731 return ret;
1732}
1733
1734static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
1735 PLCI *plci, APPL *appl, API_PARSE *msg)
1736{
1737 word Info = 0;
1738 word i = 0;
1739
1740 word selector;
1741 word SSreq;
1742 long relatedPLCIvalue;
1743 DIVA_CAPI_ADAPTER *relatedadapter;
1744 byte *SSparms = "";
1745 byte RCparms[] = "\x05\x00\x00\x02\x00\x00";
1746 byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
1747 API_PARSE *parms;
1748 API_PARSE ss_parms[11];
1749 PLCI *rplci;
1750 byte cai[15];
1751 dword d;
1752 API_PARSE dummy;
1753
1754 dbug(1, dprintf("facility_req"));
1755 for (i = 0; i < 9; i++) ss_parms[i].length = 0;
1756
1757 parms = &msg[1];
1758
1759 if (!a)
1760 {
1761 dbug(1, dprintf("wrong Ctrl"));
1762 Info = _WRONG_IDENTIFIER;
1763 }
1764
1765 selector = GET_WORD(msg[0].info);
1766
1767 if (!Info)
1768 {
1769 switch (selector)
1770 {
1771 case SELECTOR_HANDSET:
1772 Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT);
1773 break;
1774
1775 case SELECTOR_SU_SERV:
1776 if (!msg[1].length)
1777 {
1778 Info = _WRONG_MESSAGE_FORMAT;
1779 break;
1780 }
1781 SSreq = GET_WORD(&(msg[1].info[1]));
1782 PUT_WORD(&RCparms[1], SSreq);
1783 SSparms = RCparms;
1784 switch (SSreq)
1785 {
1786 case S_GET_SUPPORTED_SERVICES:
1787 if ((i = get_plci(a)))
1788 {
1789 rplci = &a->plci[i - 1];
1790 rplci->appl = appl;
1791 add_p(rplci, CAI, "\x01\x80");
1792 add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
1793 sig_req(rplci, ASSIGN, DSIG_ID);
1794 send_req(rplci);
1795 }
1796 else
1797 {
1798 PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
1799 SSparms = (byte *)SSstruct;
1800 break;
1801 }
1802 rplci->internal_command = GETSERV_REQ_PEND;
1803 rplci->number = Number;
1804 rplci->appl = appl;
1805 sig_req(rplci, S_SUPPORTED, 0);
1806 send_req(rplci);
1807 return false;
1808 break;
1809
1810 case S_LISTEN:
1811 if (parms->length == 7)
1812 {
1813 if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
1814 {
1815 dbug(1, dprintf("format wrong"));
1816 Info = _WRONG_MESSAGE_FORMAT;
1817 break;
1818 }
1819 }
1820 else
1821 {
1822 Info = _WRONG_MESSAGE_FORMAT;
1823 break;
1824 }
1825 a->Notification_Mask[appl->Id - 1] = GET_DWORD(ss_parms[2].info);
1826 if (a->Notification_Mask[appl->Id - 1] & SMASK_MWI) /* MWI active? */
1827 {
1828 if ((i = get_plci(a)))
1829 {
1830 rplci = &a->plci[i - 1];
1831 rplci->appl = appl;
1832 add_p(rplci, CAI, "\x01\x80");
1833 add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
1834 sig_req(rplci, ASSIGN, DSIG_ID);
1835 send_req(rplci);
1836 }
1837 else
1838 {
1839 break;
1840 }
1841 rplci->internal_command = GET_MWI_STATE;
1842 rplci->number = Number;
1843 sig_req(rplci, MWI_POLL, 0);
1844 send_req(rplci);
1845 }
1846 break;
1847
1848 case S_HOLD:
1849 api_parse(&parms->info[1], (word)parms->length, "ws", ss_parms);
1850 if (plci && plci->State && plci->SuppState == IDLE)
1851 {
1852 plci->SuppState = HOLD_REQUEST;
1853 plci->command = C_HOLD_REQ;
1854 add_s(plci, CAI, &ss_parms[1]);
1855 sig_req(plci, CALL_HOLD, 0);
1856 send_req(plci);
1857 return false;
1858 }
1859 else Info = 0x3010; /* wrong state */
1860 break;
1861 case S_RETRIEVE:
1862 if (plci && plci->State && plci->SuppState == CALL_HELD)
1863 {
1864 if (Id & EXT_CONTROLLER)
1865 {
1866 if (AdvCodecSupport(a, plci, appl, 0))
1867 {
1868 Info = 0x3010; /* wrong state */
1869 break;
1870 }
1871 }
1872 else plci->tel = 0;
1873
1874 plci->SuppState = RETRIEVE_REQUEST;
1875 plci->command = C_RETRIEVE_REQ;
1876 if (plci->spoofed_msg == SPOOFING_REQUIRED)
1877 {
1878 plci->spoofed_msg = CALL_RETRIEVE;
1879 plci->internal_command = BLOCK_PLCI;
1880 plci->command = 0;
1881 dbug(1, dprintf("Spoof"));
1882 return false;
1883 }
1884 else
1885 {
1886 sig_req(plci, CALL_RETRIEVE, 0);
1887 send_req(plci);
1888 return false;
1889 }
1890 }
1891 else Info = 0x3010; /* wrong state */
1892 break;
1893 case S_SUSPEND:
1894 if (parms->length)
1895 {
1896 if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms))
1897 {
1898 dbug(1, dprintf("format wrong"));
1899 Info = _WRONG_MESSAGE_FORMAT;
1900 break;
1901 }
1902 }
1903 if (plci && plci->State)
1904 {
1905 add_s(plci, CAI, &ss_parms[2]);
1906 plci->command = SUSPEND_REQ;
1907 sig_req(plci, SUSPEND, 0);
1908 plci->State = SUSPENDING;
1909 send_req(plci);
1910 }
1911 else Info = 0x3010; /* wrong state */
1912 break;
1913
1914 case S_RESUME:
1915 if (!(i = get_plci(a)))
1916 {
1917 Info = _OUT_OF_PLCI;
1918 break;
1919 }
1920 rplci = &a->plci[i - 1];
1921 rplci->appl = appl;
1922 rplci->number = Number;
1923 rplci->tel = 0;
1924 rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
1925 /* check 'external controller' bit for codec support */
1926 if (Id & EXT_CONTROLLER)
1927 {
1928 if (AdvCodecSupport(a, rplci, appl, 0))
1929 {
1930 rplci->Id = 0;
1931 Info = 0x300A;
1932 break;
1933 }
1934 }
1935 if (parms->length)
1936 {
1937 if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms))
1938 {
1939 dbug(1, dprintf("format wrong"));
1940 rplci->Id = 0;
1941 Info = _WRONG_MESSAGE_FORMAT;
1942 break;
1943 }
1944 }
1945 dummy.length = 0;
1946 dummy.info = "\x00";
1947 add_b1(rplci, &dummy, 0, 0);
1948 if (a->Info_Mask[appl->Id - 1] & 0x200)
1949 {
1950 /* early B3 connect (CIP mask bit 9) no release after a disc */
1951 add_p(rplci, LLI, "\x01\x01");
1952 }
1953 add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
1954 sig_req(rplci, ASSIGN, DSIG_ID);
1955 send_req(rplci);
1956 add_s(rplci, CAI, &ss_parms[2]);
1957 rplci->command = RESUME_REQ;
1958 sig_req(rplci, RESUME, 0);
1959 rplci->State = RESUMING;
1960 send_req(rplci);
1961 break;
1962
1963 case S_CONF_BEGIN: /* Request */
1964 case S_CONF_DROP:
1965 case S_CONF_ISOLATE:
1966 case S_CONF_REATTACH:
1967 if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
1968 {
1969 dbug(1, dprintf("format wrong"));
1970 Info = _WRONG_MESSAGE_FORMAT;
1971 break;
1972 }
1973 if (plci && plci->State && ((plci->SuppState == IDLE) || (plci->SuppState == CALL_HELD)))
1974 {
1975 d = GET_DWORD(ss_parms[2].info);
1976 if (d >= 0x80)
1977 {
1978 dbug(1, dprintf("format wrong"));
1979 Info = _WRONG_MESSAGE_FORMAT;
1980 break;
1981 }
1982 plci->ptyState = (byte)SSreq;
1983 plci->command = 0;
1984 cai[0] = 2;
1985 switch (SSreq)
1986 {
1987 case S_CONF_BEGIN:
1988 cai[1] = CONF_BEGIN;
1989 plci->internal_command = CONF_BEGIN_REQ_PEND;
1990 break;
1991 case S_CONF_DROP:
1992 cai[1] = CONF_DROP;
1993 plci->internal_command = CONF_DROP_REQ_PEND;
1994 break;
1995 case S_CONF_ISOLATE:
1996 cai[1] = CONF_ISOLATE;
1997 plci->internal_command = CONF_ISOLATE_REQ_PEND;
1998 break;
1999 case S_CONF_REATTACH:
2000 cai[1] = CONF_REATTACH;
2001 plci->internal_command = CONF_REATTACH_REQ_PEND;
2002 break;
2003 }
2004 cai[2] = (byte)d; /* Conference Size resp. PartyId */
2005 add_p(plci, CAI, cai);
2006 sig_req(plci, S_SERVICE, 0);
2007 send_req(plci);
2008 return false;
2009 }
2010 else Info = 0x3010; /* wrong state */
2011 break;
2012
2013 case S_ECT:
2014 case S_3PTY_BEGIN:
2015 case S_3PTY_END:
2016 case S_CONF_ADD:
2017 if (parms->length == 7)
2018 {
2019 if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
2020 {
2021 dbug(1, dprintf("format wrong"));
2022 Info = _WRONG_MESSAGE_FORMAT;
2023 break;
2024 }
2025 }
2026 else if (parms->length == 8) /* workaround for the T-View-S */
2027 {
2028 if (api_parse(&parms->info[1], (word)parms->length, "wbdb", ss_parms))
2029 {
2030 dbug(1, dprintf("format wrong"));
2031 Info = _WRONG_MESSAGE_FORMAT;
2032 break;
2033 }
2034 }
2035 else
2036 {
2037 Info = _WRONG_MESSAGE_FORMAT;
2038 break;
2039 }
2040 if (!msg[1].length)
2041 {
2042 Info = _WRONG_MESSAGE_FORMAT;
2043 break;
2044 }
2045 if (!plci)
2046 {
2047 Info = _WRONG_IDENTIFIER;
2048 break;
2049 }
2050 relatedPLCIvalue = GET_DWORD(ss_parms[2].info);
2051 relatedPLCIvalue &= 0x0000FFFF;
2052 dbug(1, dprintf("PTY/ECT/addCONF,relPLCI=%lx", relatedPLCIvalue));
2053 /* controller starts with 0 up to (max_adapter - 1) */
2054 if (((relatedPLCIvalue & 0x7f) == 0)
2055 || (MapController((byte)(relatedPLCIvalue & 0x7f)) == 0)
2056 || (MapController((byte)(relatedPLCIvalue & 0x7f)) > max_adapter))
2057 {
2058 if (SSreq == S_3PTY_END)
2059 {
2060 dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI"));
2061 rplci = plci;
2062 }
2063 else
2064 {
2065 Info = 0x3010; /* wrong state */
2066 break;
2067 }
2068 }
2069 else
2070 {
2071 relatedadapter = &adapter[MapController((byte)(relatedPLCIvalue & 0x7f)) - 1];
2072 relatedPLCIvalue >>= 8;
2073 /* find PLCI PTR*/
2074 for (i = 0, rplci = NULL; i < relatedadapter->max_plci; i++)
2075 {
2076 if (relatedadapter->plci[i].Id == (byte)relatedPLCIvalue)
2077 {
2078 rplci = &relatedadapter->plci[i];
2079 }
2080 }
2081 if (!rplci || !relatedPLCIvalue)
2082 {
2083 if (SSreq == S_3PTY_END)
2084 {
2085 dbug(1, dprintf("use 2nd PLCI=PLCI"));
2086 rplci = plci;
2087 }
2088 else
2089 {
2090 Info = 0x3010; /* wrong state */
2091 break;
2092 }
2093 }
2094 }
2095/*
2096 dbug(1, dprintf("rplci:%x", rplci));
2097 dbug(1, dprintf("plci:%x", plci));
2098 dbug(1, dprintf("rplci->ptyState:%x", rplci->ptyState));
2099 dbug(1, dprintf("plci->ptyState:%x", plci->ptyState));
2100 dbug(1, dprintf("SSreq:%x", SSreq));
2101 dbug(1, dprintf("rplci->internal_command:%x", rplci->internal_command));
2102 dbug(1, dprintf("rplci->appl:%x", rplci->appl));
2103 dbug(1, dprintf("rplci->Id:%x", rplci->Id));
2104*/
2105 /* send PTY/ECT req, cannot check all states because of US stuff */
2106 if (!rplci->internal_command && rplci->appl)
2107 {
2108 plci->command = 0;
2109 rplci->relatedPTYPLCI = plci;
2110 plci->relatedPTYPLCI = rplci;
2111 rplci->ptyState = (byte)SSreq;
2112 if (SSreq == S_ECT)
2113 {
2114 rplci->internal_command = ECT_REQ_PEND;
2115 cai[1] = ECT_EXECUTE;
2116
2117 rplci->vswitchstate = 0;
2118 rplci->vsprot = 0;
2119 rplci->vsprotdialect = 0;
2120 plci->vswitchstate = 0;
2121 plci->vsprot = 0;
2122 plci->vsprotdialect = 0;
2123
2124 }
2125 else if (SSreq == S_CONF_ADD)
2126 {
2127 rplci->internal_command = CONF_ADD_REQ_PEND;
2128 cai[1] = CONF_ADD;
2129 }
2130 else
2131 {
2132 rplci->internal_command = PTY_REQ_PEND;
2133 cai[1] = (byte)(SSreq - 3);
2134 }
2135 rplci->number = Number;
2136 if (plci != rplci) /* explicit invocation */
2137 {
2138 cai[0] = 2;
2139 cai[2] = plci->Sig.Id;
2140 dbug(1, dprintf("explicit invocation"));
2141 }
2142 else
2143 {
2144 dbug(1, dprintf("implicit invocation"));
2145 cai[0] = 1;
2146 }
2147 add_p(rplci, CAI, cai);
2148 sig_req(rplci, S_SERVICE, 0);
2149 send_req(rplci);
2150 return false;
2151 }
2152 else
2153 {
2154 dbug(0, dprintf("Wrong line"));
2155 Info = 0x3010; /* wrong state */
2156 break;
2157 }
2158 break;
2159
2160 case S_CALL_DEFLECTION:
2161 if (api_parse(&parms->info[1], (word)parms->length, "wbwss", ss_parms))
2162 {
2163 dbug(1, dprintf("format wrong"));
2164 Info = _WRONG_MESSAGE_FORMAT;
2165 break;
2166 }
2167 if (!plci)
2168 {
2169 Info = _WRONG_IDENTIFIER;
2170 break;
2171 }
2172 /* reuse unused screening indicator */
2173 ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0]));
2174 plci->command = 0;
2175 plci->internal_command = CD_REQ_PEND;
2176 appl->CDEnable = true;
2177 cai[0] = 1;
2178 cai[1] = CALL_DEFLECTION;
2179 add_p(plci, CAI, cai);
2180 add_p(plci, CPN, ss_parms[3].info);
2181 sig_req(plci, S_SERVICE, 0);
2182 send_req(plci);
2183 return false;
2184 break;
2185
2186 case S_CALL_FORWARDING_START:
2187 if (api_parse(&parms->info[1], (word)parms->length, "wbdwwsss", ss_parms))
2188 {
2189 dbug(1, dprintf("format wrong"));
2190 Info = _WRONG_MESSAGE_FORMAT;
2191 break;
2192 }
2193
2194 if ((i = get_plci(a)))
2195 {
2196 rplci = &a->plci[i - 1];
2197 rplci->appl = appl;
2198 add_p(rplci, CAI, "\x01\x80");
2199 add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
2200 sig_req(rplci, ASSIGN, DSIG_ID);
2201 send_req(rplci);
2202 }
2203 else
2204 {
2205 Info = _OUT_OF_PLCI;
2206 break;
2207 }
2208
2209 /* reuse unused screening indicator */
2210 rplci->internal_command = CF_START_PEND;
2211 rplci->appl = appl;
2212 rplci->number = Number;
2213 appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
2214 cai[0] = 2;
2215 cai[1] = 0x70 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
2216 cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
2217 add_p(rplci, CAI, cai);
2218 add_p(rplci, OAD, ss_parms[5].info);
2219 add_p(rplci, CPN, ss_parms[6].info);
2220 sig_req(rplci, S_SERVICE, 0);
2221 send_req(rplci);
2222 return false;
2223 break;
2224
2225 case S_INTERROGATE_DIVERSION:
2226 case S_INTERROGATE_NUMBERS:
2227 case S_CALL_FORWARDING_STOP:
2228 case S_CCBS_REQUEST:
2229 case S_CCBS_DEACTIVATE:
2230 case S_CCBS_INTERROGATE:
2231 switch (SSreq)
2232 {
2233 case S_INTERROGATE_NUMBERS:
2234 if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
2235 {
2236 dbug(0, dprintf("format wrong"));
2237 Info = _WRONG_MESSAGE_FORMAT;
2238 }
2239 break;
2240 case S_CCBS_REQUEST:
2241 case S_CCBS_DEACTIVATE:
2242 if (api_parse(&parms->info[1], (word)parms->length, "wbdw", ss_parms))
2243 {
2244 dbug(0, dprintf("format wrong"));
2245 Info = _WRONG_MESSAGE_FORMAT;
2246 }
2247 break;
2248 case S_CCBS_INTERROGATE:
2249 if (api_parse(&parms->info[1], (word)parms->length, "wbdws", ss_parms))
2250 {
2251 dbug(0, dprintf("format wrong"));
2252 Info = _WRONG_MESSAGE_FORMAT;
2253 }
2254 break;
2255 default:
2256 if (api_parse(&parms->info[1], (word)parms->length, "wbdwws", ss_parms))
2257 {
2258 dbug(0, dprintf("format wrong"));
2259 Info = _WRONG_MESSAGE_FORMAT;
2260 break;
2261 }
2262 break;
2263 }
2264
2265 if (Info) break;
2266 if ((i = get_plci(a)))
2267 {
2268 rplci = &a->plci[i - 1];
2269 switch (SSreq)
2270 {
2271 case S_INTERROGATE_DIVERSION: /* use cai with S_SERVICE below */
2272 cai[1] = 0x60 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
2273 rplci->internal_command = INTERR_DIVERSION_REQ_PEND; /* move to rplci if assigned */
2274 break;
2275 case S_INTERROGATE_NUMBERS: /* use cai with S_SERVICE below */
2276 cai[1] = DIVERSION_INTERROGATE_NUM; /* Function */
2277 rplci->internal_command = INTERR_NUMBERS_REQ_PEND; /* move to rplci if assigned */
2278 break;
2279 case S_CALL_FORWARDING_STOP:
2280 rplci->internal_command = CF_STOP_PEND;
2281 cai[1] = 0x80 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
2282 break;
2283 case S_CCBS_REQUEST:
2284 cai[1] = CCBS_REQUEST;
2285 rplci->internal_command = CCBS_REQUEST_REQ_PEND;
2286 break;
2287 case S_CCBS_DEACTIVATE:
2288 cai[1] = CCBS_DEACTIVATE;
2289 rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND;
2290 break;
2291 case S_CCBS_INTERROGATE:
2292 cai[1] = CCBS_INTERROGATE;
2293 rplci->internal_command = CCBS_INTERROGATE_REQ_PEND;
2294 break;
2295 default:
2296 cai[1] = 0;
2297 break;
2298 }
2299 rplci->appl = appl;
2300 rplci->number = Number;
2301 add_p(rplci, CAI, "\x01\x80");
2302 add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
2303 sig_req(rplci, ASSIGN, DSIG_ID);
2304 send_req(rplci);
2305 }
2306 else
2307 {
2308 Info = _OUT_OF_PLCI;
2309 break;
2310 }
2311
2312 appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
2313 switch (SSreq)
2314 {
2315 case S_INTERROGATE_NUMBERS:
2316 cai[0] = 1;
2317 add_p(rplci, CAI, cai);
2318 break;
2319 case S_CCBS_REQUEST:
2320 case S_CCBS_DEACTIVATE:
2321 cai[0] = 3;
2322 PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0])));
2323 add_p(rplci, CAI, cai);
2324 break;
2325 case S_CCBS_INTERROGATE:
2326 cai[0] = 3;
2327 PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0])));
2328 add_p(rplci, CAI, cai);
2329 add_p(rplci, OAD, ss_parms[4].info);
2330 break;
2331 default:
2332 cai[0] = 2;
2333 cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
2334 add_p(rplci, CAI, cai);
2335 add_p(rplci, OAD, ss_parms[5].info);
2336 break;
2337 }
2338
2339 sig_req(rplci, S_SERVICE, 0);
2340 send_req(rplci);
2341 return false;
2342 break;
2343
2344 case S_MWI_ACTIVATE:
2345 if (api_parse(&parms->info[1], (word)parms->length, "wbwdwwwssss", ss_parms))
2346 {
2347 dbug(1, dprintf("format wrong"));
2348 Info = _WRONG_MESSAGE_FORMAT;
2349 break;
2350 }
2351 if (!plci)
2352 {
2353 if ((i = get_plci(a)))
2354 {
2355 rplci = &a->plci[i - 1];
2356 rplci->appl = appl;
2357 rplci->cr_enquiry = true;
2358 add_p(rplci, CAI, "\x01\x80");
2359 add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
2360 sig_req(rplci, ASSIGN, DSIG_ID);
2361 send_req(rplci);
2362 }
2363 else
2364 {
2365 Info = _OUT_OF_PLCI;
2366 break;
2367 }
2368 }
2369 else
2370 {
2371 rplci = plci;
2372 rplci->cr_enquiry = false;
2373 }
2374
2375 rplci->command = 0;
2376 rplci->internal_command = MWI_ACTIVATE_REQ_PEND;
2377 rplci->appl = appl;
2378 rplci->number = Number;
2379
2380 cai[0] = 13;
2381 cai[1] = ACTIVATION_MWI; /* Function */
2382 PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
2383 PUT_DWORD(&cai[4], GET_DWORD(&(ss_parms[3].info[0]))); /* Number of Messages */
2384 PUT_WORD(&cai[8], GET_WORD(&(ss_parms[4].info[0]))); /* Message Status */
2385 PUT_WORD(&cai[10], GET_WORD(&(ss_parms[5].info[0]))); /* Message Reference */
2386 PUT_WORD(&cai[12], GET_WORD(&(ss_parms[6].info[0]))); /* Invocation Mode */
2387 add_p(rplci, CAI, cai);
2388 add_p(rplci, CPN, ss_parms[7].info); /* Receiving User Number */
2389 add_p(rplci, OAD, ss_parms[8].info); /* Controlling User Number */
2390 add_p(rplci, OSA, ss_parms[9].info); /* Controlling User Provided Number */
2391 add_p(rplci, UID, ss_parms[10].info); /* Time */
2392 sig_req(rplci, S_SERVICE, 0);
2393 send_req(rplci);
2394 return false;
2395
2396 case S_MWI_DEACTIVATE:
2397 if (api_parse(&parms->info[1], (word)parms->length, "wbwwss", ss_parms))
2398 {
2399 dbug(1, dprintf("format wrong"));
2400 Info = _WRONG_MESSAGE_FORMAT;
2401 break;
2402 }
2403 if (!plci)
2404 {
2405 if ((i = get_plci(a)))
2406 {
2407 rplci = &a->plci[i - 1];
2408 rplci->appl = appl;
2409 rplci->cr_enquiry = true;
2410 add_p(rplci, CAI, "\x01\x80");
2411 add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
2412 sig_req(rplci, ASSIGN, DSIG_ID);
2413 send_req(rplci);
2414 }
2415 else
2416 {
2417 Info = _OUT_OF_PLCI;
2418 break;
2419 }
2420 }
2421 else
2422 {
2423 rplci = plci;
2424 rplci->cr_enquiry = false;
2425 }
2426
2427 rplci->command = 0;
2428 rplci->internal_command = MWI_DEACTIVATE_REQ_PEND;
2429 rplci->appl = appl;
2430 rplci->number = Number;
2431
2432 cai[0] = 5;
2433 cai[1] = DEACTIVATION_MWI; /* Function */
2434 PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
2435 PUT_WORD(&cai[4], GET_WORD(&(ss_parms[3].info[0]))); /* Invocation Mode */
2436 add_p(rplci, CAI, cai);
2437 add_p(rplci, CPN, ss_parms[4].info); /* Receiving User Number */
2438 add_p(rplci, OAD, ss_parms[5].info); /* Controlling User Number */
2439 sig_req(rplci, S_SERVICE, 0);
2440 send_req(rplci);
2441 return false;
2442
2443 default:
2444 Info = 0x300E; /* not supported */
2445 break;
2446 }
2447 break; /* case SELECTOR_SU_SERV: end */
2448
2449
2450 case SELECTOR_DTMF:
2451 return (dtmf_request(Id, Number, a, plci, appl, msg));
2452
2453
2454
2455 case SELECTOR_LINE_INTERCONNECT:
2456 return (mixer_request(Id, Number, a, plci, appl, msg));
2457
2458
2459
2460 case PRIV_SELECTOR_ECHO_CANCELLER:
2461 appl->appl_flags |= APPL_FLAG_PRIV_EC_SPEC;
2462 return (ec_request(Id, Number, a, plci, appl, msg));
2463
2464 case SELECTOR_ECHO_CANCELLER:
2465 appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC;
2466 return (ec_request(Id, Number, a, plci, appl, msg));
2467
2468
2469 case SELECTOR_V42BIS:
2470 default:
2471 Info = _FACILITY_NOT_SUPPORTED;
2472 break;
2473 } /* end of switch (selector) */
2474 }
2475
2476 dbug(1, dprintf("SendFacRc"));
2477 sendf(appl,
2478 _FACILITY_R | CONFIRM,
2479 Id,
2480 Number,
2481 "wws", Info, selector, SSparms);
2482 return false;
2483}
2484
2485static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2486 PLCI *plci, APPL *appl, API_PARSE *msg)
2487{
2488 dbug(1, dprintf("facility_res"));
2489 return false;
2490}
2491
2492static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2493 PLCI *plci, APPL *appl, API_PARSE *parms)
2494{
2495 word Info = 0;
2496 byte req;
2497 byte len;
2498 word w;
2499 word fax_control_bits, fax_feature_bits, fax_info_change;
2500 API_PARSE *ncpi;
2501 byte pvc[2];
2502
2503 API_PARSE fax_parms[9];
2504 word i;
2505
2506
2507 dbug(1, dprintf("connect_b3_req"));
2508 if (plci)
2509 {
2510 if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING)
2511 || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE))
2512 {
2513 Info = _WRONG_STATE;
2514 }
2515 else
2516 {
2517 /* local reply if assign unsuccessful
2518 or B3 protocol allows only one layer 3 connection
2519 and already connected
2520 or B2 protocol not any LAPD
2521 and connect_b3_req contradicts originate/answer direction */
2522 if (!plci->NL.Id
2523 || (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
2524 && ((plci->channels != 0)
2525 || (((plci->B2_prot != B2_SDLC) && (plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL))
2526 && ((plci->call_dir & CALL_DIR_ANSWER) && !(plci->call_dir & CALL_DIR_FORCE_OUTG_NL))))))
2527 {
2528 dbug(1, dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x",
2529 plci->channels, plci->NL.Id, plci->call_dir, plci->SuppState));
2530 Info = _WRONG_STATE;
2531 sendf(appl,
2532 _CONNECT_B3_R | CONFIRM,
2533 Id,
2534 Number,
2535 "w", Info);
2536 return false;
2537 }
2538 plci->requested_options_conn = 0;
2539
2540 req = N_CONNECT;
2541 ncpi = &parms[0];
2542 if (plci->B3_prot == 2 || plci->B3_prot == 3)
2543 {
2544 if (ncpi->length > 2)
2545 {
2546 /* check for PVC */
2547 if (ncpi->info[2] || ncpi->info[3])
2548 {
2549 pvc[0] = ncpi->info[3];
2550 pvc[1] = ncpi->info[2];
2551 add_d(plci, 2, pvc);
2552 req = N_RESET;
2553 }
2554 else
2555 {
2556 if (ncpi->info[1] & 1) req = N_CONNECT | N_D_BIT;
2557 add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
2558 }
2559 }
2560 }
2561 else if (plci->B3_prot == 5)
2562 {
2563 if (plci->NL.Id && !plci->nl_remove_id)
2564 {
2565 fax_control_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low);
2566 fax_feature_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low);
2567 if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS)
2568 || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
2569 {
2570 len = offsetof(T30_INFO, universal_6);
2571 fax_info_change = false;
2572 if (ncpi->length >= 4)
2573 {
2574 w = GET_WORD(&ncpi->info[3]);
2575 if ((w & 0x0001) != ((word)(((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & 0x0001)))
2576 {
2577 ((T30_INFO *)(plci->fax_connect_info_buffer))->resolution =
2578 (byte)((((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) |
2579 ((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0));
2580 fax_info_change = true;
2581 }
2582 fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
2583 if (w & 0x0002) /* Fax-polling request */
2584 fax_control_bits |= T30_CONTROL_BIT_REQUEST_POLLING;
2585 if ((w & 0x0004) /* Request to send / poll another document */
2586 && (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS))
2587 {
2588 fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS;
2589 }
2590 if (ncpi->length >= 6)
2591 {
2592 w = GET_WORD(&ncpi->info[5]);
2593 if (((byte) w) != ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format)
2594 {
2595 ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format = (byte) w;
2596 fax_info_change = true;
2597 }
2598
2599 if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
2600 && (GET_WORD(&ncpi->info[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */
2601 {
2602 plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD);
2603 }
2604 if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
2605 && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */
2606 {
2607 plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD);
2608 }
2609 fax_control_bits &= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_SEL_POLLING |
2610 T30_CONTROL_BIT_ACCEPT_PASSWORD);
2611 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
2612 & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
2613 {
2614 if (api_parse(&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms))
2615 Info = _WRONG_MESSAGE_FORMAT;
2616 else
2617 {
2618 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
2619 & (1L << PRIVATE_FAX_SUB_SEP_PWD))
2620 {
2621 fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
2622 if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
2623 fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
2624 }
2625 w = fax_parms[4].length;
2626 if (w > 20)
2627 w = 20;
2628 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = (byte) w;
2629 for (i = 0; i < w; i++)
2630 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1 + i];
2631 ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
2632 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
2633 w = fax_parms[5].length;
2634 if (w > 20)
2635 w = 20;
2636 plci->fax_connect_info_buffer[len++] = (byte) w;
2637 for (i = 0; i < w; i++)
2638 plci->fax_connect_info_buffer[len++] = fax_parms[5].info[1 + i];
2639 w = fax_parms[6].length;
2640 if (w > 20)
2641 w = 20;
2642 plci->fax_connect_info_buffer[len++] = (byte) w;
2643 for (i = 0; i < w; i++)
2644 plci->fax_connect_info_buffer[len++] = fax_parms[6].info[1 + i];
2645 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
2646 & (1L << PRIVATE_FAX_NONSTANDARD))
2647 {
2648 if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
2649 {
2650 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
2651 plci->fax_connect_info_buffer[len++] = 0;
2652 }
2653 else
2654 {
2655 if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
2656 plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
2657 plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
2658 for (i = 0; i < fax_parms[7].length; i++)
2659 plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
2660 }
2661 }
2662 }
2663 }
2664 else
2665 {
2666 len = offsetof(T30_INFO, universal_6);
2667 }
2668 fax_info_change = true;
2669
2670 }
2671 if (fax_control_bits != GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low))
2672 {
2673 PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits);
2674 fax_info_change = true;
2675 }
2676 }
2677 if (Info == GOOD)
2678 {
2679 plci->fax_connect_info_length = len;
2680 if (fax_info_change)
2681 {
2682 if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
2683 {
2684 start_internal_command(Id, plci, fax_connect_info_command);
2685 return false;
2686 }
2687 else
2688 {
2689 start_internal_command(Id, plci, fax_adjust_b23_command);
2690 return false;
2691 }
2692 }
2693 }
2694 }
2695 else Info = _WRONG_STATE;
2696 }
2697 else Info = _WRONG_STATE;
2698 }
2699
2700 else if (plci->B3_prot == B3_RTP)
2701 {
2702 plci->internal_req_buffer[0] = ncpi->length + 1;
2703 plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
2704 for (w = 0; w < ncpi->length; w++)
2705 plci->internal_req_buffer[2 + w] = ncpi->info[1 + w];
2706 start_internal_command(Id, plci, rtp_connect_b3_req_command);
2707 return false;
2708 }
2709
2710 if (!Info)
2711 {
2712 nl_req_ncci(plci, req, 0);
2713 return 1;
2714 }
2715 }
2716 }
2717 else Info = _WRONG_IDENTIFIER;
2718
2719 sendf(appl,
2720 _CONNECT_B3_R | CONFIRM,
2721 Id,
2722 Number,
2723 "w", Info);
2724 return false;
2725}
2726
2727static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2728 PLCI *plci, APPL *appl, API_PARSE *parms)
2729{
2730 word ncci;
2731 API_PARSE *ncpi;
2732 byte req;
2733
2734 word w;
2735
2736
2737 API_PARSE fax_parms[9];
2738 word i;
2739 byte len;
2740
2741
2742 dbug(1, dprintf("connect_b3_res"));
2743
2744 ncci = (word)(Id >> 16);
2745 if (plci && ncci) {
2746 if (a->ncci_state[ncci] == INC_CON_PENDING) {
2747 if (GET_WORD(&parms[0].info[0]) != 0)
2748 {
2749 a->ncci_state[ncci] = OUTG_REJ_PENDING;
2750 channel_request_xon(plci, a->ncci_ch[ncci]);
2751 channel_xmit_xon(plci);
2752 cleanup_ncci_data(plci, ncci);
2753 nl_req_ncci(plci, N_DISC, (byte)ncci);
2754 return 1;
2755 }
2756 a->ncci_state[ncci] = INC_ACT_PENDING;
2757
2758 req = N_CONNECT_ACK;
2759 ncpi = &parms[1];
2760 if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
2761 {
2762
2763 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
2764 & (1L << PRIVATE_FAX_NONSTANDARD))
2765 {
2766 if (((plci->B3_prot == 4) || (plci->B3_prot == 5))
2767 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
2768 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
2769 {
2770 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
2771 if (plci->fax_connect_info_length < len)
2772 {
2773 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
2774 ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
2775 }
2776 if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
2777 {
2778 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
2779 }
2780 else
2781 {
2782 if (plci->fax_connect_info_length <= len)
2783 plci->fax_connect_info_buffer[len] = 0;
2784 len += 1 + plci->fax_connect_info_buffer[len];
2785 if (plci->fax_connect_info_length <= len)
2786 plci->fax_connect_info_buffer[len] = 0;
2787 len += 1 + plci->fax_connect_info_buffer[len];
2788 if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
2789 plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
2790 plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
2791 for (i = 0; i < fax_parms[7].length; i++)
2792 plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
2793 }
2794 plci->fax_connect_info_length = len;
2795 ((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0;
2796 start_internal_command(Id, plci, fax_connect_ack_command);
2797 return false;
2798 }
2799 }
2800
2801 nl_req_ncci(plci, req, (byte)ncci);
2802 if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
2803 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
2804 {
2805 if (plci->B3_prot == 4)
2806 sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
2807 else
2808 sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
2809 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
2810 }
2811 }
2812
2813 else if (plci->B3_prot == B3_RTP)
2814 {
2815 plci->internal_req_buffer[0] = ncpi->length + 1;
2816 plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
2817 for (w = 0; w < ncpi->length; w++)
2818 plci->internal_req_buffer[2 + w] = ncpi->info[1+w];
2819 start_internal_command(Id, plci, rtp_connect_b3_res_command);
2820 return false;
2821 }
2822
2823 else
2824 {
2825 if (ncpi->length > 2) {
2826 if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT;
2827 add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
2828 }
2829 nl_req_ncci(plci, req, (byte)ncci);
2830 sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
2831 if (plci->adjust_b_restore)
2832 {
2833 plci->adjust_b_restore = false;
2834 start_internal_command(Id, plci, adjust_b_restore);
2835 }
2836 }
2837 return 1;
2838 }
2839 }
2840 return false;
2841}
2842
2843static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2844 PLCI *plci, APPL *appl, API_PARSE *parms)
2845{
2846 word ncci;
2847
2848 ncci = (word)(Id >> 16);
2849 dbug(1, dprintf("connect_b3_a_res(ncci=0x%x)", ncci));
2850
2851 if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING)
2852 && (plci->State != OUTG_DIS_PENDING))
2853 {
2854 if (a->ncci_state[ncci] == INC_ACT_PENDING) {
2855 a->ncci_state[ncci] = CONNECTED;
2856 if (plci->State != INC_CON_CONNECTED_ALERT) plci->State = CONNECTED;
2857 channel_request_xon(plci, a->ncci_ch[ncci]);
2858 channel_xmit_xon(plci);
2859 }
2860 }
2861 return false;
2862}
2863
2864static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2865 PLCI *plci, APPL *appl, API_PARSE *parms)
2866{
2867 word Info;
2868 word ncci;
2869 API_PARSE *ncpi;
2870
2871 dbug(1, dprintf("disconnect_b3_req"));
2872
2873 Info = _WRONG_IDENTIFIER;
2874 ncci = (word)(Id >> 16);
2875 if (plci && ncci)
2876 {
2877 Info = _WRONG_STATE;
2878 if ((a->ncci_state[ncci] == CONNECTED)
2879 || (a->ncci_state[ncci] == OUTG_CON_PENDING)
2880 || (a->ncci_state[ncci] == INC_CON_PENDING)
2881 || (a->ncci_state[ncci] == INC_ACT_PENDING))
2882 {
2883 a->ncci_state[ncci] = OUTG_DIS_PENDING;
2884 channel_request_xon(plci, a->ncci_ch[ncci]);
2885 channel_xmit_xon(plci);
2886
2887 if (a->ncci[ncci].data_pending
2888 && ((plci->B3_prot == B3_TRANSPARENT)
2889 || (plci->B3_prot == B3_T30)
2890 || (plci->B3_prot == B3_T30_WITH_EXTENSIONS)))
2891 {
2892 plci->send_disc = (byte)ncci;
2893 plci->command = 0;
2894 return false;
2895 }
2896 else
2897 {
2898 cleanup_ncci_data(plci, ncci);
2899
2900 if (plci->B3_prot == 2 || plci->B3_prot == 3)
2901 {
2902 ncpi = &parms[0];
2903 if (ncpi->length > 3)
2904 {
2905 add_d(plci, (word)(ncpi->length - 3), (byte *)&(ncpi->info[4]));
2906 }
2907 }
2908 nl_req_ncci(plci, N_DISC, (byte)ncci);
2909 }
2910 return 1;
2911 }
2912 }
2913 sendf(appl,
2914 _DISCONNECT_B3_R | CONFIRM,
2915 Id,
2916 Number,
2917 "w", Info);
2918 return false;
2919}
2920
2921static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2922 PLCI *plci, APPL *appl, API_PARSE *parms)
2923{
2924 word ncci;
2925 word i;
2926
2927 ncci = (word)(Id >> 16);
2928 dbug(1, dprintf("disconnect_b3_res(ncci=0x%x", ncci));
2929 if (plci && ncci) {
2930 plci->requested_options_conn = 0;
2931 plci->fax_connect_info_length = 0;
2932 plci->ncpi_state = 0x00;
2933 if (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
2934 && ((plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL)))
2935 {
2936 plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
2937 }
2938 for (i = 0; i < MAX_CHANNELS_PER_PLCI && plci->inc_dis_ncci_table[i] != (byte)ncci; i++);
2939 if (i < MAX_CHANNELS_PER_PLCI) {
2940 if (plci->channels)plci->channels--;
2941 for (; i < MAX_CHANNELS_PER_PLCI - 1; i++) plci->inc_dis_ncci_table[i] = plci->inc_dis_ncci_table[i + 1];
2942 plci->inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI - 1] = 0;
2943
2944 ncci_free_receive_buffers(plci, ncci);
2945
2946 if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) {
2947 if (plci->State == SUSPENDING) {
2948 sendf(plci->appl,
2949 _FACILITY_I,
2950 Id & 0xffffL,
2951 0,
2952 "ws", (word)3, "\x03\x04\x00\x00");
2953 sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
2954 }
2955 plci_remove(plci);
2956 plci->State = IDLE;
2957 }
2958 }
2959 else
2960 {
2961 if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
2962 && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
2963 && (a->ncci_state[ncci] == INC_DIS_PENDING))
2964 {
2965 ncci_free_receive_buffers(plci, ncci);
2966
2967 nl_req_ncci(plci, N_EDATA, (byte)ncci);
2968
2969 plci->adapter->ncci_state[ncci] = IDLE;
2970 start_internal_command(Id, plci, fax_disconnect_command);
2971 return 1;
2972 }
2973 }
2974 }
2975 return false;
2976}
2977
2978static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2979 PLCI *plci, APPL *appl, API_PARSE *parms)
2980{
2981 NCCI *ncci_ptr;
2982 DATA_B3_DESC *data;
2983 word Info;
2984 word ncci;
2985 word i;
2986
2987 dbug(1, dprintf("data_b3_req"));
2988
2989 Info = _WRONG_IDENTIFIER;
2990 ncci = (word)(Id >> 16);
2991 dbug(1, dprintf("ncci=0x%x, plci=0x%x", ncci, plci));
2992
2993 if (plci && ncci)
2994 {
2995 Info = _WRONG_STATE;
2996 if ((a->ncci_state[ncci] == CONNECTED)
2997 || (a->ncci_state[ncci] == INC_ACT_PENDING))
2998 {
2999 /* queue data */
3000 ncci_ptr = &(a->ncci[ncci]);
3001 i = ncci_ptr->data_out + ncci_ptr->data_pending;
3002 if (i >= MAX_DATA_B3)
3003 i -= MAX_DATA_B3;
3004 data = &(ncci_ptr->DBuffer[i]);
3005 data->Number = Number;
3006 if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue)))
3007 && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
3008 {
3009
3010 data->P = (byte *)(long)(*((dword *)(parms[0].info)));
3011
3012 }
3013 else
3014 data->P = TransmitBufferSet(appl, *(dword *)parms[0].info);
3015 data->Length = GET_WORD(parms[1].info);
3016 data->Handle = GET_WORD(parms[2].info);
3017 data->Flags = GET_WORD(parms[3].info);
3018 (ncci_ptr->data_pending)++;
3019
3020 /* check for delivery confirmation */
3021 if (data->Flags & 0x0004)
3022 {
3023 i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending;
3024 if (i >= MAX_DATA_ACK)
3025 i -= MAX_DATA_ACK;
3026 ncci_ptr->DataAck[i].Number = data->Number;
3027 ncci_ptr->DataAck[i].Handle = data->Handle;
3028 (ncci_ptr->data_ack_pending)++;
3029 }
3030
3031 send_data(plci);
3032 return false;
3033 }
3034 }
3035 if (appl)
3036 {
3037 if (plci)
3038 {
3039 if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue)))
3040 && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
3041 {
3042
3043 TransmitBufferFree(appl, (byte *)(long)(*((dword *)(parms[0].info))));
3044
3045 }
3046 }
3047 sendf(appl,
3048 _DATA_B3_R | CONFIRM,
3049 Id,
3050 Number,
3051 "ww", GET_WORD(parms[2].info), Info);
3052 }
3053 return false;
3054}
3055
3056static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3057 PLCI *plci, APPL *appl, API_PARSE *parms)
3058{
3059 word n;
3060 word ncci;
3061 word NCCIcode;
3062
3063 dbug(1, dprintf("data_b3_res"));
3064
3065 ncci = (word)(Id >> 16);
3066 if (plci && ncci) {
3067 n = GET_WORD(parms[0].info);
3068 dbug(1, dprintf("free(%d)", n));
3069 NCCIcode = ncci | (((word) a->Id) << 8);
3070 if (n < appl->MaxBuffer &&
3071 appl->DataNCCI[n] == NCCIcode &&
3072 (byte)(appl->DataFlags[n] >> 8) == plci->Id) {
3073 dbug(1, dprintf("found"));
3074 appl->DataNCCI[n] = 0;
3075
3076 if (channel_can_xon(plci, a->ncci_ch[ncci])) {
3077 channel_request_xon(plci, a->ncci_ch[ncci]);
3078 }
3079 channel_xmit_xon(plci);
3080
3081 if (appl->DataFlags[n] & 4) {
3082 nl_req_ncci(plci, N_DATA_ACK, (byte)ncci);
3083 return 1;
3084 }
3085 }
3086 }
3087 return false;
3088}
3089
3090static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3091 PLCI *plci, APPL *appl, API_PARSE *parms)
3092{
3093 word Info;
3094 word ncci;
3095
3096 dbug(1, dprintf("reset_b3_req"));
3097
3098 Info = _WRONG_IDENTIFIER;
3099 ncci = (word)(Id >> 16);
3100 if (plci && ncci)
3101 {
3102 Info = _WRONG_STATE;
3103 switch (plci->B3_prot)
3104 {
3105 case B3_ISO8208:
3106 case B3_X25_DCE:
3107 if (a->ncci_state[ncci] == CONNECTED)
3108 {
3109 nl_req_ncci(plci, N_RESET, (byte)ncci);
3110 send_req(plci);
3111 Info = GOOD;
3112 }
3113 break;
3114 case B3_TRANSPARENT:
3115 if (a->ncci_state[ncci] == CONNECTED)
3116 {
3117 start_internal_command(Id, plci, reset_b3_command);
3118 Info = GOOD;
3119 }
3120 break;
3121 }
3122 }
3123 /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */
3124 sendf(appl,
3125 _RESET_B3_R | CONFIRM,
3126 Id,
3127 Number,
3128 "w", Info);
3129 return false;
3130}
3131
3132static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3133 PLCI *plci, APPL *appl, API_PARSE *parms)
3134{
3135 word ncci;
3136
3137 dbug(1, dprintf("reset_b3_res"));
3138
3139 ncci = (word)(Id >> 16);
3140 if (plci && ncci) {
3141 switch (plci->B3_prot)
3142 {
3143 case B3_ISO8208:
3144 case B3_X25_DCE:
3145 if (a->ncci_state[ncci] == INC_RES_PENDING)
3146 {
3147 a->ncci_state[ncci] = CONNECTED;
3148 nl_req_ncci(plci, N_RESET_ACK, (byte)ncci);
3149 return true;
3150 }
3151 break;
3152 }
3153 }
3154 return false;
3155}
3156
3157static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3158 PLCI *plci, APPL *appl, API_PARSE *parms)
3159{
3160 word ncci;
3161 API_PARSE *ncpi;
3162 byte req;
3163
3164 dbug(1, dprintf("connect_b3_t90_a_res"));
3165
3166 ncci = (word)(Id >> 16);
3167 if (plci && ncci) {
3168 if (a->ncci_state[ncci] == INC_ACT_PENDING) {
3169 a->ncci_state[ncci] = CONNECTED;
3170 }
3171 else if (a->ncci_state[ncci] == INC_CON_PENDING) {
3172 a->ncci_state[ncci] = CONNECTED;
3173
3174 req = N_CONNECT_ACK;
3175
3176 /* parms[0]==0 for CAPI original message definition! */
3177 if (parms[0].info) {
3178 ncpi = &parms[1];
3179 if (ncpi->length > 2) {
3180 if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT;
3181 add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
3182 }
3183 }
3184 nl_req_ncci(plci, req, (byte)ncci);
3185 return 1;
3186 }
3187 }
3188 return false;
3189}
3190
3191
3192static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3193 PLCI *plci, APPL *appl, API_PARSE *msg)
3194{
3195 word Info = 0;
3196 word i;
3197 byte tel;
3198 API_PARSE bp_parms[7];
3199
3200 if (!plci || !msg)
3201 {
3202 Info = _WRONG_IDENTIFIER;
3203 }
3204 else
3205 {
3206 dbug(1, dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x",
3207 msg->length, plci->Id, plci->tel, plci->NL.Id, plci->appl, plci->SuppState));
3208 dbug(1, dprintf("PlciState=0x%x", plci->State));
3209 for (i = 0; i < 7; i++) bp_parms[i].length = 0;
3210
3211 /* check if no channel is open, no B3 connected only */
3212 if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) || (plci->State == INC_DIS_PENDING)
3213 || (plci->SuppState != IDLE) || plci->channels || plci->nl_remove_id)
3214 {
3215 Info = _WRONG_STATE;
3216 }
3217 /* check message format and fill bp_parms pointer */
3218 else if (msg->length && api_parse(&msg->info[1], (word)msg->length, "wwwsss", bp_parms))
3219 {
3220 Info = _WRONG_MESSAGE_FORMAT;
3221 }
3222 else
3223 {
3224 if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT)) /* send alert tone inband to the network, */
3225 { /* e.g. Qsig or RBS or Cornet-N or xess PRI */
3226 if (Id & EXT_CONTROLLER)
3227 {
3228 sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */
3229 return 0;
3230 }
3231 plci->State = INC_CON_CONNECTED_ALERT;
3232 plci->appl = appl;
3233 __clear_bit(appl->Id - 1, plci->c_ind_mask_table);
3234 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
3235 /* disconnect the other appls its quasi a connect */
3236 for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
3237 sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
3238 }
3239
3240 api_save_msg(msg, "s", &plci->saved_msg);
3241 tel = plci->tel;
3242 if (Id & EXT_CONTROLLER)
3243 {
3244 if (tel) /* external controller in use by this PLCI */
3245 {
3246 if (a->AdvSignalAppl && a->AdvSignalAppl != appl)
3247 {
3248 dbug(1, dprintf("Ext_Ctrl in use 1"));
3249 Info = _WRONG_STATE;
3250 }
3251 }
3252 else /* external controller NOT in use by this PLCI ? */
3253 {
3254 if (a->AdvSignalPLCI)
3255 {
3256 dbug(1, dprintf("Ext_Ctrl in use 2"));
3257 Info = _WRONG_STATE;
3258 }
3259 else /* activate the codec */
3260 {
3261 dbug(1, dprintf("Ext_Ctrl start"));
3262 if (AdvCodecSupport(a, plci, appl, 0))
3263 {
3264 dbug(1, dprintf("Error in codec procedures"));
3265 Info = _WRONG_STATE;
3266 }
3267 else if (plci->spoofed_msg == SPOOFING_REQUIRED) /* wait until codec is active */
3268 {
3269 plci->spoofed_msg = AWAITING_SELECT_B;
3270 plci->internal_command = BLOCK_PLCI; /* lock other commands */
3271 plci->command = 0;
3272 dbug(1, dprintf("continue if codec loaded"));
3273 return false;
3274 }
3275 }
3276 }
3277 }
3278 else /* external controller bit is OFF */
3279 {
3280 if (tel) /* external controller in use, need to switch off */
3281 {
3282 if (a->AdvSignalAppl == appl)
3283 {
3284 CodecIdCheck(a, plci);
3285 plci->tel = 0;
3286 plci->adv_nl = 0;
3287 dbug(1, dprintf("Ext_Ctrl disable"));
3288 }
3289 else
3290 {
3291 dbug(1, dprintf("Ext_Ctrl not requested"));
3292 }
3293 }
3294 }
3295 if (!Info)
3296 {
3297 if (plci->call_dir & CALL_DIR_OUT)
3298 plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
3299 else if (plci->call_dir & CALL_DIR_IN)
3300 plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER;
3301 start_internal_command(Id, plci, select_b_command);
3302 return false;
3303 }
3304 }
3305 }
3306 sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", Info);
3307 return false;
3308}
3309
3310static byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3311 PLCI *plci, APPL *appl, API_PARSE *parms)
3312{
3313 word command;
3314 word i;
3315 word ncci;
3316 API_PARSE *m;
3317 API_PARSE m_parms[5];
3318 word codec;
3319 byte req;
3320 byte ch;
3321 byte dir;
3322 static byte chi[2] = {0x01, 0x00};
3323 static byte lli[2] = {0x01, 0x00};
3324 static byte codec_cai[2] = {0x01, 0x01};
3325 static byte null_msg = {0};
3326 static API_PARSE null_parms = { 0, &null_msg };
3327 PLCI *v_plci;
3328 word Info = 0;
3329
3330 dbug(1, dprintf("manufacturer_req"));
3331 for (i = 0; i < 5; i++) m_parms[i].length = 0;
3332
3333 if (GET_DWORD(parms[0].info) != _DI_MANU_ID) {
3334 Info = _WRONG_MESSAGE_FORMAT;
3335 }
3336 command = GET_WORD(parms[1].info);
3337 m = &parms[2];
3338 if (!Info)
3339 {
3340 switch (command) {
3341 case _DI_ASSIGN_PLCI:
3342 if (api_parse(&m->info[1], (word)m->length, "wbbs", m_parms)) {
3343 Info = _WRONG_MESSAGE_FORMAT;
3344 break;
3345 }
3346 codec = GET_WORD(m_parms[0].info);
3347 ch = m_parms[1].info[0];
3348 dir = m_parms[2].info[0];
3349 if ((i = get_plci(a))) {
3350 plci = &a->plci[i - 1];
3351 plci->appl = appl;
3352 plci->command = _MANUFACTURER_R;
3353 plci->m_command = command;
3354 plci->number = Number;
3355 plci->State = LOCAL_CONNECT;
3356 Id = (((word)plci->Id << 8) | plci->adapter->Id | 0x80);
3357 dbug(1, dprintf("ManCMD,plci=0x%x", Id));
3358
3359 if ((ch == 1 || ch == 2) && (dir <= 2)) {
3360 chi[1] = (byte)(0x80 | ch);
3361 lli[1] = 0;
3362 plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
3363 switch (codec)
3364 {
3365 case 0:
3366 Info = add_b1(plci, &m_parms[3], 0, 0);
3367 break;
3368 case 1:
3369 add_p(plci, CAI, codec_cai);
3370 break;
3371 /* manual 'swich on' to the codec support without signalling */
3372 /* first 'assign plci' with this function, then use */
3373 case 2:
3374 if (AdvCodecSupport(a, plci, appl, 0)) {
3375 Info = _RESOURCE_ERROR;
3376 }
3377 else {
3378 Info = add_b1(plci, &null_parms, 0, B1_FACILITY_LOCAL);
3379 lli[1] = 0x10; /* local call codec stream */
3380 }
3381 break;
3382 }
3383
3384 plci->State = LOCAL_CONNECT;
3385 plci->manufacturer = true;
3386 plci->command = _MANUFACTURER_R;
3387 plci->m_command = command;
3388 plci->number = Number;
3389
3390 if (!Info)
3391 {
3392 add_p(plci, LLI, lli);
3393 add_p(plci, CHI, chi);
3394 add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
3395 sig_req(plci, ASSIGN, DSIG_ID);
3396
3397 if (!codec)
3398 {
3399 Info = add_b23(plci, &m_parms[3]);
3400 if (!Info)
3401 {
3402 nl_req_ncci(plci, ASSIGN, 0);
3403 send_req(plci);
3404 }
3405 }
3406 if (!Info)
3407 {
3408 dbug(1, dprintf("dir=0x%x,spoof=0x%x", dir, plci->spoofed_msg));
3409 if (plci->spoofed_msg == SPOOFING_REQUIRED)
3410 {
3411 api_save_msg(m_parms, "wbbs", &plci->saved_msg);
3412 plci->spoofed_msg = AWAITING_MANUF_CON;
3413 plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
3414 plci->command = 0;
3415 send_req(plci);
3416 return false;
3417 }
3418 if (dir == 1) {
3419 sig_req(plci, CALL_REQ, 0);
3420 }
3421 else if (!dir) {
3422 sig_req(plci, LISTEN_REQ, 0);
3423 }
3424 send_req(plci);
3425 }
3426 else
3427 {
3428 sendf(appl,
3429 _MANUFACTURER_R | CONFIRM,
3430 Id,
3431 Number,
3432 "dww", _DI_MANU_ID, command, Info);
3433 return 2;
3434 }
3435 }
3436 }
3437 }
3438 else Info = _OUT_OF_PLCI;
3439 break;
3440
3441 case _DI_IDI_CTRL:
3442 if (!plci)
3443 {
3444 Info = _WRONG_IDENTIFIER;
3445 break;
3446 }
3447 if (api_parse(&m->info[1], (word)m->length, "bs", m_parms)) {
3448 Info = _WRONG_MESSAGE_FORMAT;
3449 break;
3450 }
3451 req = m_parms[0].info[0];
3452 plci->command = _MANUFACTURER_R;
3453 plci->m_command = command;
3454 plci->number = Number;
3455 if (req == CALL_REQ)
3456 {
3457 plci->b_channel = getChannel(&m_parms[1]);
3458 mixer_set_bchannel_id_esc(plci, plci->b_channel);
3459 if (plci->spoofed_msg == SPOOFING_REQUIRED)
3460 {
3461 plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON;
3462 plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
3463 plci->command = 0;
3464 break;
3465 }
3466 }
3467 else if (req == LAW_REQ)
3468 {
3469 plci->cr_enquiry = true;
3470 }
3471 add_ss(plci, FTY, &m_parms[1]);
3472 sig_req(plci, req, 0);
3473 send_req(plci);
3474 if (req == HANGUP)
3475 {
3476 if (plci->NL.Id && !plci->nl_remove_id)
3477 {
3478 if (plci->channels)
3479 {
3480 for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
3481 {
3482 if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
3483 {
3484 a->ncci_state[ncci] = OUTG_DIS_PENDING;
3485 cleanup_ncci_data(plci, ncci);
3486 nl_req_ncci(plci, N_DISC, (byte)ncci);
3487 }
3488 }
3489 }
3490 mixer_remove(plci);
3491 nl_req_ncci(plci, REMOVE, 0);
3492 send_req(plci);
3493 }
3494 }
3495 break;
3496
3497 case _DI_SIG_CTRL:
3498 /* signalling control for loop activation B-channel */
3499 if (!plci)
3500 {
3501 Info = _WRONG_IDENTIFIER;
3502 break;
3503 }
3504 if (m->length) {
3505 plci->command = _MANUFACTURER_R;
3506 plci->number = Number;
3507 add_ss(plci, FTY, m);
3508 sig_req(plci, SIG_CTRL, 0);
3509 send_req(plci);
3510 }
3511 else Info = _WRONG_MESSAGE_FORMAT;
3512 break;
3513
3514 case _DI_RXT_CTRL:
3515 /* activation control for receiver/transmitter B-channel */
3516 if (!plci)
3517 {
3518 Info = _WRONG_IDENTIFIER;
3519 break;
3520 }
3521 if (m->length) {
3522 plci->command = _MANUFACTURER_R;
3523 plci->number = Number;
3524 add_ss(plci, FTY, m);
3525 sig_req(plci, DSP_CTRL, 0);
3526 send_req(plci);
3527 }
3528 else Info = _WRONG_MESSAGE_FORMAT;
3529 break;
3530
3531 case _DI_ADV_CODEC:
3532 case _DI_DSP_CTRL:
3533 /* TEL_CTRL commands to support non standard adjustments: */
3534 /* Ring on/off, Handset micro volume, external micro vol. */
3535 /* handset+external speaker volume, receiver+transm. gain,*/
3536 /* handsfree on (hookinfo off), set mixer command */
3537
3538 if (command == _DI_ADV_CODEC)
3539 {
3540 if (!a->AdvCodecPLCI) {
3541 Info = _WRONG_STATE;
3542 break;
3543 }
3544 v_plci = a->AdvCodecPLCI;
3545 }
3546 else
3547 {
3548 if (plci
3549 && (m->length >= 3)
3550 && (m->info[1] == 0x1c)
3551 && (m->info[2] >= 1))
3552 {
3553 if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS)
3554 {
3555 if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI))
3556 {
3557 Info = _WRONG_STATE;
3558 break;
3559 }
3560 a->adv_voice_coef_length = m->info[2] - 1;
3561 if (a->adv_voice_coef_length > m->length - 3)
3562 a->adv_voice_coef_length = (byte)(m->length - 3);
3563 if (a->adv_voice_coef_length > ADV_VOICE_COEF_BUFFER_SIZE)
3564 a->adv_voice_coef_length = ADV_VOICE_COEF_BUFFER_SIZE;
3565 for (i = 0; i < a->adv_voice_coef_length; i++)
3566 a->adv_voice_coef_buffer[i] = m->info[4 + i];
3567 if (plci->B1_facilities & B1_FACILITY_VOICE)
3568 adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE);
3569 break;
3570 }
3571 else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS)
3572 {
3573 if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS))
3574 {
3575 Info = _FACILITY_NOT_SUPPORTED;
3576 break;
3577 }
3578
3579 plci->dtmf_parameter_length = m->info[2] - 1;
3580 if (plci->dtmf_parameter_length > m->length - 3)
3581 plci->dtmf_parameter_length = (byte)(m->length - 3);
3582 if (plci->dtmf_parameter_length > DTMF_PARAMETER_BUFFER_SIZE)
3583 plci->dtmf_parameter_length = DTMF_PARAMETER_BUFFER_SIZE;
3584 for (i = 0; i < plci->dtmf_parameter_length; i++)
3585 plci->dtmf_parameter_buffer[i] = m->info[4 + i];
3586 if (plci->B1_facilities & B1_FACILITY_DTMFR)
3587 dtmf_parameter_write(plci);
3588 break;
3589
3590 }
3591 }
3592 v_plci = plci;
3593 }
3594
3595 if (!v_plci)
3596 {
3597 Info = _WRONG_IDENTIFIER;
3598 break;
3599 }
3600 if (m->length) {
3601 add_ss(v_plci, FTY, m);
3602 sig_req(v_plci, TEL_CTRL, 0);
3603 send_req(v_plci);
3604 }
3605 else Info = _WRONG_MESSAGE_FORMAT;
3606
3607 break;
3608
3609 case _DI_OPTIONS_REQUEST:
3610 if (api_parse(&m->info[1], (word)m->length, "d", m_parms)) {
3611 Info = _WRONG_MESSAGE_FORMAT;
3612 break;
3613 }
3614 if (GET_DWORD(m_parms[0].info) & ~a->man_profile.private_options)
3615 {
3616 Info = _FACILITY_NOT_SUPPORTED;
3617 break;
3618 }
3619 a->requested_options_table[appl->Id - 1] = GET_DWORD(m_parms[0].info);
3620 break;
3621
3622
3623
3624 default:
3625 Info = _WRONG_MESSAGE_FORMAT;
3626 break;
3627 }
3628 }
3629
3630 sendf(appl,
3631 _MANUFACTURER_R | CONFIRM,
3632 Id,
3633 Number,
3634 "dww", _DI_MANU_ID, command, Info);
3635 return false;
3636}
3637
3638
3639static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3640 PLCI *plci, APPL *appl, API_PARSE *msg)
3641{
3642 word indication;
3643
3644 API_PARSE m_parms[3];
3645 API_PARSE *ncpi;
3646 API_PARSE fax_parms[9];
3647 word i;
3648 byte len;
3649
3650
3651 dbug(1, dprintf("manufacturer_res"));
3652
3653 if ((msg[0].length == 0)
3654 || (msg[1].length == 0)
3655 || (GET_DWORD(msg[0].info) != _DI_MANU_ID))
3656 {
3657 return false;
3658 }
3659 indication = GET_WORD(msg[1].info);
3660 switch (indication)
3661 {
3662
3663 case _DI_NEGOTIATE_B3:
3664 if (!plci)
3665 break;
3666 if (((plci->B3_prot != 4) && (plci->B3_prot != 5))
3667 || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
3668 {
3669 dbug(1, dprintf("wrong state for NEGOTIATE_B3 parameters"));
3670 break;
3671 }
3672 if (api_parse(&msg[2].info[1], msg[2].length, "ws", m_parms))
3673 {
3674 dbug(1, dprintf("wrong format in NEGOTIATE_B3 parameters"));
3675 break;
3676 }
3677 ncpi = &m_parms[1];
3678 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
3679 if (plci->fax_connect_info_length < len)
3680 {
3681 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
3682 ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
3683 }
3684 if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
3685 {
3686 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
3687 }
3688 else
3689 {
3690 if (plci->fax_connect_info_length <= len)
3691 plci->fax_connect_info_buffer[len] = 0;
3692 len += 1 + plci->fax_connect_info_buffer[len];
3693 if (plci->fax_connect_info_length <= len)
3694 plci->fax_connect_info_buffer[len] = 0;
3695 len += 1 + plci->fax_connect_info_buffer[len];
3696 if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
3697 plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
3698 plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
3699 for (i = 0; i < fax_parms[7].length; i++)
3700 plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
3701 }
3702 plci->fax_connect_info_length = len;
3703 plci->fax_edata_ack_length = plci->fax_connect_info_length;
3704 start_internal_command(Id, plci, fax_edata_ack_command);
3705 break;
3706
3707 }
3708 return false;
3709}
3710
3711/*------------------------------------------------------------------*/
3712/* IDI callback function */
3713/*------------------------------------------------------------------*/
3714
3715void callback(ENTITY *e)
3716{
3717 DIVA_CAPI_ADAPTER *a;
3718 APPL *appl;
3719 PLCI *plci;
3720 CAPI_MSG *m;
3721 word i, j;
3722 byte rc;
3723 byte ch;
3724 byte req;
3725 byte global_req;
3726 int no_cancel_rc;
3727
3728 dbug(1, dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)",
3729 (e->user[0] + 1) & 0x7fff, e->Id, e->Req, e->Rc, e->Ind));
3730
3731 a = &(adapter[(byte)e->user[0]]);
3732 plci = &(a->plci[e->user[1]]);
3733 no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a);
3734
3735 /*
3736 If new protocol code and new XDI is used then CAPI should work
3737 fully in accordance with IDI cpec an look on callback field instead
3738 of Rc field for return codes.
3739 */
3740 if (((e->complete == 0xff) && no_cancel_rc) ||
3741 (e->Rc && !no_cancel_rc)) {
3742 rc = e->Rc;
3743 ch = e->RcCh;
3744 req = e->Req;
3745 e->Rc = 0;
3746
3747 if (e->user[0] & 0x8000)
3748 {
3749 /*
3750 If REMOVE request was sent then we have to wait until
3751 return code with Id set to zero arrives.
3752 All other return codes should be ignored.
3753 */
3754 if (req == REMOVE)
3755 {
3756 if (e->Id)
3757 {
3758 dbug(1, dprintf("cancel RC in REMOVE state"));
3759 return;
3760 }
3761 channel_flow_control_remove(plci);
3762 for (i = 0; i < 256; i++)
3763 {
3764 if (a->FlowControlIdTable[i] == plci->nl_remove_id)
3765 a->FlowControlIdTable[i] = 0;
3766 }
3767 plci->nl_remove_id = 0;
3768 if (plci->rx_dma_descriptor > 0) {
3769 diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1);
3770 plci->rx_dma_descriptor = 0;
3771 }
3772 }
3773 if (rc == OK_FC)
3774 {
3775 a->FlowControlIdTable[ch] = e->Id;
3776 a->FlowControlSkipTable[ch] = 0;
3777
3778 a->ch_flow_control[ch] |= N_OK_FC_PENDING;
3779 a->ch_flow_plci[ch] = plci->Id;
3780 plci->nl_req = 0;
3781 }
3782 else
3783 {
3784 /*
3785 Cancel return codes self, if feature was requested
3786 */
3787 if (no_cancel_rc && (a->FlowControlIdTable[ch] == e->Id) && e->Id) {
3788 a->FlowControlIdTable[ch] = 0;
3789 if ((rc == OK) && a->FlowControlSkipTable[ch]) {
3790 dbug(3, dprintf("XDI CAPI: RC cancelled Id:0x02, Ch:%02x", e->Id, ch));
3791 return;
3792 }
3793 }
3794
3795 if (a->ch_flow_control[ch] & N_OK_FC_PENDING)
3796 {
3797 a->ch_flow_control[ch] &= ~N_OK_FC_PENDING;
3798 if (ch == e->ReqCh)
3799 plci->nl_req = 0;
3800 }
3801 else
3802 plci->nl_req = 0;
3803 }
3804 if (plci->nl_req)
3805 control_rc(plci, 0, rc, ch, 0, true);
3806 else
3807 {
3808 if (req == N_XON)
3809 {
3810 channel_x_on(plci, ch);
3811 if (plci->internal_command)
3812 control_rc(plci, req, rc, ch, 0, true);
3813 }
3814 else
3815 {
3816 if (plci->nl_global_req)
3817 {
3818 global_req = plci->nl_global_req;
3819 plci->nl_global_req = 0;
3820 if (rc != ASSIGN_OK) {
3821 e->Id = 0;
3822 if (plci->rx_dma_descriptor > 0) {
3823 diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1);
3824 plci->rx_dma_descriptor = 0;
3825 }
3826 }
3827 channel_xmit_xon(plci);
3828 control_rc(plci, 0, rc, ch, global_req, true);
3829 }
3830 else if (plci->data_sent)
3831 {
3832 channel_xmit_xon(plci);
3833 plci->data_sent = false;
3834 plci->NL.XNum = 1;
3835 data_rc(plci, ch);
3836 if (plci->internal_command)
3837 control_rc(plci, req, rc, ch, 0, true);
3838 }
3839 else
3840 {
3841 channel_xmit_xon(plci);
3842 control_rc(plci, req, rc, ch, 0, true);
3843 }
3844 }
3845 }
3846 }
3847 else
3848 {
3849 /*
3850 If REMOVE request was sent then we have to wait until
3851 return code with Id set to zero arrives.
3852 All other return codes should be ignored.
3853 */
3854 if (req == REMOVE)
3855 {
3856 if (e->Id)
3857 {
3858 dbug(1, dprintf("cancel RC in REMOVE state"));
3859 return;
3860 }
3861 plci->sig_remove_id = 0;
3862 }
3863 plci->sig_req = 0;
3864 if (plci->sig_global_req)
3865 {
3866 global_req = plci->sig_global_req;
3867 plci->sig_global_req = 0;
3868 if (rc != ASSIGN_OK)
3869 e->Id = 0;
3870 channel_xmit_xon(plci);
3871 control_rc(plci, 0, rc, ch, global_req, false);
3872 }
3873 else
3874 {
3875 channel_xmit_xon(plci);
3876 control_rc(plci, req, rc, ch, 0, false);
3877 }
3878 }
3879 /*
3880 Again: in accordance with IDI spec Rc and Ind can't be delivered in the
3881 same callback. Also if new XDI and protocol code used then jump
3882 direct to finish.
3883 */
3884 if (no_cancel_rc) {
3885 channel_xmit_xon(plci);
3886 goto capi_callback_suffix;
3887 }
3888 }
3889
3890 channel_xmit_xon(plci);
3891
3892 if (e->Ind) {
3893 if (e->user[0] & 0x8000) {
3894 byte Ind = e->Ind & 0x0f;
3895 byte Ch = e->IndCh;
3896 if (((Ind == N_DISC) || (Ind == N_DISC_ACK)) &&
3897 (a->ch_flow_plci[Ch] == plci->Id)) {
3898 if (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK) {
3899 dbug(3, dprintf("XDI CAPI: I: pending N-XON Ch:%02x", Ch));
3900 }
3901 a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
3902 }
3903 nl_ind(plci);
3904 if ((e->RNR != 1) &&
3905 (a->ch_flow_plci[Ch] == plci->Id) &&
3906 (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK)) {
3907 a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
3908 dbug(3, dprintf("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch));
3909 }
3910 } else {
3911 sig_ind(plci);
3912 }
3913 e->Ind = 0;
3914 }
3915
3916capi_callback_suffix:
3917
3918 while (!plci->req_in
3919 && !plci->internal_command
3920 && (plci->msg_in_write_pos != plci->msg_in_read_pos))
3921 {
3922 j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos;
3923
3924 i = (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc;
3925
3926 m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]);
3927 appl = *((APPL **)(&((byte *)(plci->msg_in_queue))[j + i]));
3928 dbug(1, dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d",
3929 m->header.command, plci->msg_in_write_pos, plci->msg_in_read_pos, plci->msg_in_wrap_pos));
3930 if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
3931 {
3932 plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
3933 plci->msg_in_read_pos = i + MSG_IN_OVERHEAD;
3934 }
3935 else
3936 {
3937 plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD;
3938 }
3939 if (plci->msg_in_read_pos == plci->msg_in_write_pos)
3940 {
3941 plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
3942 plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
3943 }
3944 else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
3945 {
3946 plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
3947 plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
3948 }
3949 i = api_put(appl, m);
3950 if (i != 0)
3951 {
3952 if (m->header.command == _DATA_B3_R)
3953
3954 TransmitBufferFree(appl, (byte *)(long)(m->info.data_b3_req.Data));
3955
3956 dbug(1, dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
3957 break;
3958 }
3959
3960 if (plci->li_notify_update)
3961 {
3962 plci->li_notify_update = false;
3963 mixer_notify_update(plci, false);
3964 }
3965
3966 }
3967 send_data(plci);
3968 send_req(plci);
3969}
3970
3971
3972static void control_rc(PLCI *plci, byte req, byte rc, byte ch, byte global_req,
3973 byte nl_rc)
3974{
3975 dword Id;
3976 dword rId;
3977 word Number;
3978 word Info = 0;
3979 word i;
3980 word ncci;
3981 DIVA_CAPI_ADAPTER *a;
3982 APPL *appl;
3983 PLCI *rplci;
3984 byte SSparms[] = "\x05\x00\x00\x02\x00\x00";
3985 byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
3986
3987 if (!plci) {
3988 dbug(0, dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc));
3989 return;
3990 }
3991 dbug(1, dprintf("req0_in/out=%d/%d", plci->req_in, plci->req_out));
3992 if (plci->req_in != plci->req_out)
3993 {
3994 if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK))
3995 {
3996 dbug(1, dprintf("req_1return"));
3997 return;
3998 }
3999 /* cancel outstanding request on the PLCI after SIG ASSIGN failure */
4000 }
4001 plci->req_in = plci->req_in_start = plci->req_out = 0;
4002 dbug(1, dprintf("control_rc"));
4003
4004 appl = plci->appl;
4005 a = plci->adapter;
4006 ncci = a->ch_ncci[ch];
4007 if (appl)
4008 {
4009 Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id;
4010 if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER;
4011 Number = plci->number;
4012 dbug(1, dprintf("Contr_RC-Id=%08lx,plci=%x,tel=%x, entity=0x%x, command=0x%x, int_command=0x%x", Id, plci->Id, plci->tel, plci->Sig.Id, plci->command, plci->internal_command));
4013 dbug(1, dprintf("channels=0x%x", plci->channels));
4014 if (plci_remove_check(plci))
4015 return;
4016 if (req == REMOVE && rc == ASSIGN_OK)
4017 {
4018 sig_req(plci, HANGUP, 0);
4019 sig_req(plci, REMOVE, 0);
4020 send_req(plci);
4021 }
4022 if (plci->command)
4023 {
4024 switch (plci->command)
4025 {
4026 case C_HOLD_REQ:
4027 dbug(1, dprintf("HoldRC=0x%x", rc));
4028 SSparms[1] = (byte)S_HOLD;
4029 if (rc != OK)
4030 {
4031 plci->SuppState = IDLE;
4032 Info = 0x2001;
4033 }
4034 sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms);
4035 break;
4036
4037 case C_RETRIEVE_REQ:
4038 dbug(1, dprintf("RetrieveRC=0x%x", rc));
4039 SSparms[1] = (byte)S_RETRIEVE;
4040 if (rc != OK)
4041 {
4042 plci->SuppState = CALL_HELD;
4043 Info = 0x2001;
4044 }
4045 sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms);
4046 break;
4047
4048 case _INFO_R:
4049 dbug(1, dprintf("InfoRC=0x%x", rc));
4050 if (rc != OK) Info = _WRONG_STATE;
4051 sendf(appl, _INFO_R | CONFIRM, Id, Number, "w", Info);
4052 break;
4053
4054 case _CONNECT_R:
4055 dbug(1, dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x", req, rc, global_req, nl_rc));
4056 if (plci->State == INC_DIS_PENDING)
4057 break;
4058 if (plci->Sig.Id != 0xff)
4059 {
4060 if (((global_req == ASSIGN) && (rc != ASSIGN_OK))
4061 || (!nl_rc && (req == CALL_REQ) && (rc != OK)))
4062 {
4063 dbug(1, dprintf("No more IDs/Call_Req failed"));
4064 sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
4065 plci_remove(plci);
4066 plci->State = IDLE;
4067 break;
4068 }
4069 if (plci->State != LOCAL_CONNECT) plci->State = OUTG_CON_PENDING;
4070 sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
4071 }
4072 else /* D-ch activation */
4073 {
4074 if (rc != ASSIGN_OK)
4075 {
4076 dbug(1, dprintf("No more IDs/X.25 Call_Req failed"));
4077 sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
4078 plci_remove(plci);
4079 plci->State = IDLE;
4080 break;
4081 }
4082 sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
4083 sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "sss", "", "", "");
4084 plci->State = INC_ACT_PENDING;
4085 }
4086 break;
4087
4088 case _CONNECT_I | RESPONSE:
4089 if (plci->State != INC_DIS_PENDING)
4090 plci->State = INC_CON_ACCEPT;
4091 break;
4092
4093 case _DISCONNECT_R:
4094 if (plci->State == INC_DIS_PENDING)
4095 break;
4096 if (plci->Sig.Id != 0xff)
4097 {
4098 plci->State = OUTG_DIS_PENDING;
4099 sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0);
4100 }
4101 break;
4102
4103 case SUSPEND_REQ:
4104 break;
4105
4106 case RESUME_REQ:
4107 break;
4108
4109 case _CONNECT_B3_R:
4110 if (rc != OK)
4111 {
4112 sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
4113 break;
4114 }
4115 ncci = get_ncci(plci, ch, 0);
4116 Id = (Id & 0xffff) | (((dword) ncci) << 16);
4117 plci->channels++;
4118 if (req == N_RESET)
4119 {
4120 a->ncci_state[ncci] = INC_ACT_PENDING;
4121 sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
4122 sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
4123 }
4124 else
4125 {
4126 a->ncci_state[ncci] = OUTG_CON_PENDING;
4127 sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
4128 }
4129 break;
4130
4131 case _CONNECT_B3_I | RESPONSE:
4132 break;
4133
4134 case _RESET_B3_R:
4135/* sendf(appl, _RESET_B3_R | CONFIRM, Id, Number, "w", 0);*/
4136 break;
4137
4138 case _DISCONNECT_B3_R:
4139 sendf(appl, _DISCONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
4140 break;
4141
4142 case _MANUFACTURER_R:
4143 break;
4144
4145 case PERM_LIST_REQ:
4146 if (rc != OK)
4147 {
4148 Info = _WRONG_IDENTIFIER;
4149 sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info);
4150 plci_remove(plci);
4151 }
4152 else
4153 sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info);
4154 break;
4155
4156 default:
4157 break;
4158 }
4159 plci->command = 0;
4160 }
4161 else if (plci->internal_command)
4162 {
4163 switch (plci->internal_command)
4164 {
4165 case BLOCK_PLCI:
4166 return;
4167
4168 case GET_MWI_STATE:
4169 if (rc == OK) /* command supported, wait for indication */
4170 {
4171 return;
4172 }
4173 plci_remove(plci);
4174 break;
4175
4176 /* Get Supported Services */
4177 case GETSERV_REQ_PEND:
4178 if (rc == OK) /* command supported, wait for indication */
4179 {
4180 break;
4181 }
4182 PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
4183 sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", 0, 3, SSstruct);
4184 plci_remove(plci);
4185 break;
4186
4187 case INTERR_DIVERSION_REQ_PEND: /* Interrogate Parameters */
4188 case INTERR_NUMBERS_REQ_PEND:
4189 case CF_START_PEND: /* Call Forwarding Start pending */
4190 case CF_STOP_PEND: /* Call Forwarding Stop pending */
4191 case CCBS_REQUEST_REQ_PEND:
4192 case CCBS_DEACTIVATE_REQ_PEND:
4193 case CCBS_INTERROGATE_REQ_PEND:
4194 switch (plci->internal_command)
4195 {
4196 case INTERR_DIVERSION_REQ_PEND:
4197 SSparms[1] = S_INTERROGATE_DIVERSION;
4198 break;
4199 case INTERR_NUMBERS_REQ_PEND:
4200 SSparms[1] = S_INTERROGATE_NUMBERS;
4201 break;
4202 case CF_START_PEND:
4203 SSparms[1] = S_CALL_FORWARDING_START;
4204 break;
4205 case CF_STOP_PEND:
4206 SSparms[1] = S_CALL_FORWARDING_STOP;
4207 break;
4208 case CCBS_REQUEST_REQ_PEND:
4209 SSparms[1] = S_CCBS_REQUEST;
4210 break;
4211 case CCBS_DEACTIVATE_REQ_PEND:
4212 SSparms[1] = S_CCBS_DEACTIVATE;
4213 break;
4214 case CCBS_INTERROGATE_REQ_PEND:
4215 SSparms[1] = S_CCBS_INTERROGATE;
4216 break;
4217 }
4218 if (global_req == ASSIGN)
4219 {
4220 dbug(1, dprintf("AssignDiversion_RC=0x%x/0x%x", req, rc));
4221 return;
4222 }
4223 if (!plci->appl) break;
4224 if (rc == ISDN_GUARD_REJ)
4225 {
4226 Info = _CAPI_GUARD_ERROR;
4227 }
4228 else if (rc != OK)
4229 {
4230 Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED;
4231 }
4232 sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7,
4233 plci->number, "wws", Info, (word)3, SSparms);
4234 if (Info) plci_remove(plci);
4235 break;
4236
4237 /* 3pty conference pending */
4238 case PTY_REQ_PEND:
4239 if (!plci->relatedPTYPLCI) break;
4240 rplci = plci->relatedPTYPLCI;
4241 SSparms[1] = plci->ptyState;
4242 rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
4243 if (rplci->tel) rId |= EXT_CONTROLLER;
4244 if (rc != OK)
4245 {
4246 Info = 0x300E; /* not supported */
4247 plci->relatedPTYPLCI = NULL;
4248 plci->ptyState = 0;
4249 }
4250 sendf(rplci->appl,
4251 _FACILITY_R | CONFIRM,
4252 rId,
4253 plci->number,
4254 "wws", Info, (word)3, SSparms);
4255 break;
4256
4257 /* Explicit Call Transfer pending */
4258 case ECT_REQ_PEND:
4259 dbug(1, dprintf("ECT_RC=0x%x/0x%x", req, rc));
4260 if (!plci->relatedPTYPLCI) break;
4261 rplci = plci->relatedPTYPLCI;
4262 SSparms[1] = S_ECT;
4263 rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
4264 if (rplci->tel) rId |= EXT_CONTROLLER;
4265 if (rc != OK)
4266 {
4267 Info = 0x300E; /* not supported */
4268 plci->relatedPTYPLCI = NULL;
4269 plci->ptyState = 0;
4270 }
4271 sendf(rplci->appl,
4272 _FACILITY_R | CONFIRM,
4273 rId,
4274 plci->number,
4275 "wws", Info, (word)3, SSparms);
4276 break;
4277
4278 case _MANUFACTURER_R:
4279 dbug(1, dprintf("_Manufacturer_R=0x%x/0x%x", req, rc));
4280 if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
4281 {
4282 dbug(1, dprintf("No more IDs"));
4283 sendf(appl, _MANUFACTURER_R | CONFIRM, Id, Number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI);
4284 plci_remove(plci); /* after codec init, internal codec commands pending */
4285 }
4286 break;
4287
4288 case _CONNECT_R:
4289 dbug(1, dprintf("_Connect_R=0x%x/0x%x", req, rc));
4290 if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
4291 {
4292 dbug(1, dprintf("No more IDs"));
4293 sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
4294 plci_remove(plci); /* after codec init, internal codec commands pending */
4295 }
4296 break;
4297
4298 case PERM_COD_HOOK: /* finished with Hook_Ind */
4299 return;
4300
4301 case PERM_COD_CALL:
4302 dbug(1, dprintf("***Codec Connect_Pending A, Rc = 0x%x", rc));
4303 plci->internal_command = PERM_COD_CONN_PEND;
4304 return;
4305
4306 case PERM_COD_ASSIGN:
4307 dbug(1, dprintf("***Codec Assign A, Rc = 0x%x", rc));
4308 if (rc != ASSIGN_OK) break;
4309 sig_req(plci, CALL_REQ, 0);
4310 send_req(plci);
4311 plci->internal_command = PERM_COD_CALL;
4312 return;
4313
4314 /* Null Call Reference Request pending */
4315 case C_NCR_FAC_REQ:
4316 dbug(1, dprintf("NCR_FAC=0x%x/0x%x", req, rc));
4317 if (global_req == ASSIGN)
4318 {
4319 if (rc == ASSIGN_OK)
4320 {
4321 return;
4322 }
4323 else
4324 {
4325 sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE);
4326 appl->NullCREnable = false;
4327 plci_remove(plci);
4328 }
4329 }
4330 else if (req == NCR_FACILITY)
4331 {
4332 if (rc == OK)
4333 {
4334 sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", 0);
4335 }
4336 else
4337 {
4338 sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE);
4339 appl->NullCREnable = false;
4340 }
4341 plci_remove(plci);
4342 }
4343 break;
4344
4345 case HOOK_ON_REQ:
4346 if (plci->channels)
4347 {
4348 if (a->ncci_state[ncci] == CONNECTED)
4349 {
4350 a->ncci_state[ncci] = OUTG_DIS_PENDING;
4351 cleanup_ncci_data(plci, ncci);
4352 nl_req_ncci(plci, N_DISC, (byte)ncci);
4353 }
4354 break;
4355 }
4356 break;
4357
4358 case HOOK_OFF_REQ:
4359 if (plci->State == INC_DIS_PENDING)
4360 break;
4361 sig_req(plci, CALL_REQ, 0);
4362 send_req(plci);
4363 plci->State = OUTG_CON_PENDING;
4364 break;
4365
4366
4367 case MWI_ACTIVATE_REQ_PEND:
4368 case MWI_DEACTIVATE_REQ_PEND:
4369 if (global_req == ASSIGN && rc == ASSIGN_OK)
4370 {
4371 dbug(1, dprintf("MWI_REQ assigned"));
4372 return;
4373 }
4374 else if (rc != OK)
4375 {
4376 if (rc == WRONG_IE)
4377 {
4378 Info = 0x2007; /* Illegal message parameter coding */
4379 dbug(1, dprintf("MWI_REQ invalid parameter"));
4380 }
4381 else
4382 {
4383 Info = 0x300B; /* not supported */
4384 dbug(1, dprintf("MWI_REQ not supported"));
4385 }
4386 /* 0x3010: Request not allowed in this state */
4387 PUT_WORD(&SSparms[4], 0x300E); /* SS not supported */
4388
4389 }
4390 if (plci->internal_command == MWI_ACTIVATE_REQ_PEND)
4391 {
4392 PUT_WORD(&SSparms[1], S_MWI_ACTIVATE);
4393 }
4394 else PUT_WORD(&SSparms[1], S_MWI_DEACTIVATE);
4395
4396 if (plci->cr_enquiry)
4397 {
4398 sendf(plci->appl,
4399 _FACILITY_R | CONFIRM,
4400 Id & 0xf,
4401 plci->number,
4402 "wws", Info, (word)3, SSparms);
4403 if (rc != OK) plci_remove(plci);
4404 }
4405 else
4406 {
4407 sendf(plci->appl,
4408 _FACILITY_R | CONFIRM,
4409 Id,
4410 plci->number,
4411 "wws", Info, (word)3, SSparms);
4412 }
4413 break;
4414
4415 case CONF_BEGIN_REQ_PEND:
4416 case CONF_ADD_REQ_PEND:
4417 case CONF_SPLIT_REQ_PEND:
4418 case CONF_DROP_REQ_PEND:
4419 case CONF_ISOLATE_REQ_PEND:
4420 case CONF_REATTACH_REQ_PEND:
4421 dbug(1, dprintf("CONF_RC=0x%x/0x%x", req, rc));
4422 if ((plci->internal_command == CONF_ADD_REQ_PEND) && (!plci->relatedPTYPLCI)) break;
4423 rplci = plci;
4424 rId = Id;
4425 switch (plci->internal_command)
4426 {
4427 case CONF_BEGIN_REQ_PEND:
4428 SSparms[1] = S_CONF_BEGIN;
4429 break;
4430 case CONF_ADD_REQ_PEND:
4431 SSparms[1] = S_CONF_ADD;
4432 rplci = plci->relatedPTYPLCI;
4433 rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
4434 break;
4435 case CONF_SPLIT_REQ_PEND:
4436 SSparms[1] = S_CONF_SPLIT;
4437 break;
4438 case CONF_DROP_REQ_PEND:
4439 SSparms[1] = S_CONF_DROP;
4440 break;
4441 case CONF_ISOLATE_REQ_PEND:
4442 SSparms[1] = S_CONF_ISOLATE;
4443 break;
4444 case CONF_REATTACH_REQ_PEND:
4445 SSparms[1] = S_CONF_REATTACH;
4446 break;
4447 }
4448
4449 if (rc != OK)
4450 {
4451 Info = 0x300E; /* not supported */
4452 plci->relatedPTYPLCI = NULL;
4453 plci->ptyState = 0;
4454 }
4455 sendf(rplci->appl,
4456 _FACILITY_R | CONFIRM,
4457 rId,
4458 plci->number,
4459 "wws", Info, (word)3, SSparms);
4460 break;
4461
4462 case VSWITCH_REQ_PEND:
4463 if (rc != OK)
4464 {
4465 if (plci->relatedPTYPLCI)
4466 {
4467 plci->relatedPTYPLCI->vswitchstate = 0;
4468 plci->relatedPTYPLCI->vsprot = 0;
4469 plci->relatedPTYPLCI->vsprotdialect = 0;
4470 }
4471 plci->vswitchstate = 0;
4472 plci->vsprot = 0;
4473 plci->vsprotdialect = 0;
4474 }
4475 else
4476 {
4477 if (plci->relatedPTYPLCI &&
4478 plci->vswitchstate == 1 &&
4479 plci->relatedPTYPLCI->vswitchstate == 3) /* join complete */
4480 plci->vswitchstate = 3;
4481 }
4482 break;
4483
4484 /* Call Deflection Request pending (SSCT) */
4485 case CD_REQ_PEND:
4486 SSparms[1] = S_CALL_DEFLECTION;
4487 if (rc != OK)
4488 {
4489 Info = 0x300E; /* not supported */
4490 plci->appl->CDEnable = 0;
4491 }
4492 sendf(plci->appl, _FACILITY_R | CONFIRM, Id,
4493 plci->number, "wws", Info, (word)3, SSparms);
4494 break;
4495
4496 case RTP_CONNECT_B3_REQ_COMMAND_2:
4497 if (rc == OK)
4498 {
4499 ncci = get_ncci(plci, ch, 0);
4500 Id = (Id & 0xffff) | (((dword) ncci) << 16);
4501 plci->channels++;
4502 a->ncci_state[ncci] = OUTG_CON_PENDING;
4503 }
4504 /* fall through */
4505
4506 default:
4507 if (plci->internal_command_queue[0])
4508 {
4509 (*(plci->internal_command_queue[0]))(Id, plci, rc);
4510 if (plci->internal_command)
4511 return;
4512 }
4513 break;
4514 }
4515 next_internal_command(Id, plci);
4516 }
4517 }
4518 else /* appl==0 */
4519 {
4520 Id = ((word)plci->Id << 8) | plci->adapter->Id;
4521 if (plci->tel) Id |= EXT_CONTROLLER;
4522
4523 switch (plci->internal_command)
4524 {
4525 case BLOCK_PLCI:
4526 return;
4527
4528 case START_L1_SIG_ASSIGN_PEND:
4529 case REM_L1_SIG_ASSIGN_PEND:
4530 if (global_req == ASSIGN)
4531 {
4532 break;
4533 }
4534 else
4535 {
4536 dbug(1, dprintf("***L1 Req rem PLCI"));
4537 plci->internal_command = 0;
4538 sig_req(plci, REMOVE, 0);
4539 send_req(plci);
4540 }
4541 break;
4542
4543 /* Call Deflection Request pending, just no appl ptr assigned */
4544 case CD_REQ_PEND:
4545 SSparms[1] = S_CALL_DEFLECTION;
4546 if (rc != OK)
4547 {
4548 Info = 0x300E; /* not supported */
4549 }
4550 for (i = 0; i < max_appl; i++)
4551 {
4552 if (application[i].CDEnable)
4553 {
4554 if (!application[i].Id) application[i].CDEnable = 0;
4555 else
4556 {
4557 sendf(&application[i], _FACILITY_R | CONFIRM, Id,
4558 plci->number, "wws", Info, (word)3, SSparms);
4559 if (Info) application[i].CDEnable = 0;
4560 }
4561 }
4562 }
4563 plci->internal_command = 0;
4564 break;
4565
4566 case PERM_COD_HOOK: /* finished with Hook_Ind */
4567 return;
4568
4569 case PERM_COD_CALL:
4570 plci->internal_command = PERM_COD_CONN_PEND;
4571 dbug(1, dprintf("***Codec Connect_Pending, Rc = 0x%x", rc));
4572 return;
4573
4574 case PERM_COD_ASSIGN:
4575 dbug(1, dprintf("***Codec Assign, Rc = 0x%x", rc));
4576 plci->internal_command = 0;
4577 if (rc != ASSIGN_OK) break;
4578 plci->internal_command = PERM_COD_CALL;
4579 sig_req(plci, CALL_REQ, 0);
4580 send_req(plci);
4581 return;
4582
4583 case LISTEN_SIG_ASSIGN_PEND:
4584 if (rc == ASSIGN_OK)
4585 {
4586 plci->internal_command = 0;
4587 dbug(1, dprintf("ListenCheck, new SIG_ID = 0x%x", plci->Sig.Id));
4588 add_p(plci, ESC, "\x02\x18\x00"); /* support call waiting */
4589 sig_req(plci, INDICATE_REQ, 0);
4590 send_req(plci);
4591 }
4592 else
4593 {
4594 dbug(1, dprintf("ListenCheck failed (assignRc=0x%x)", rc));
4595 a->listen_active--;
4596 plci_remove(plci);
4597 plci->State = IDLE;
4598 }
4599 break;
4600
4601 case USELAW_REQ:
4602 if (global_req == ASSIGN)
4603 {
4604 if (rc == ASSIGN_OK)
4605 {
4606 sig_req(plci, LAW_REQ, 0);
4607 send_req(plci);
4608 dbug(1, dprintf("Auto-Law assigned"));
4609 }
4610 else
4611 {
4612 dbug(1, dprintf("Auto-Law assign failed"));
4613 a->automatic_law = 3;
4614 plci->internal_command = 0;
4615 a->automatic_lawPLCI = NULL;
4616 }
4617 break;
4618 }
4619 else if (req == LAW_REQ && rc == OK)
4620 {
4621 dbug(1, dprintf("Auto-Law initiated"));
4622 a->automatic_law = 2;
4623 plci->internal_command = 0;
4624 }
4625 else
4626 {
4627 dbug(1, dprintf("Auto-Law not supported"));
4628 a->automatic_law = 3;
4629 plci->internal_command = 0;
4630 sig_req(plci, REMOVE, 0);
4631 send_req(plci);
4632 a->automatic_lawPLCI = NULL;
4633 }
4634 break;
4635 }
4636 plci_remove_check(plci);
4637 }
4638}
4639
4640static void data_rc(PLCI *plci, byte ch)
4641{
4642 dword Id;
4643 DIVA_CAPI_ADAPTER *a;
4644 NCCI *ncci_ptr;
4645 DATA_B3_DESC *data;
4646 word ncci;
4647
4648 if (plci->appl)
4649 {
4650 TransmitBufferFree(plci->appl, plci->data_sent_ptr);
4651 a = plci->adapter;
4652 ncci = a->ch_ncci[ch];
4653 if (ncci && (a->ncci_plci[ncci] == plci->Id))
4654 {
4655 ncci_ptr = &(a->ncci[ncci]);
4656 dbug(1, dprintf("data_out=%d, data_pending=%d", ncci_ptr->data_out, ncci_ptr->data_pending));
4657 if (ncci_ptr->data_pending)
4658 {
4659 data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
4660 if (!(data->Flags & 4) && a->ncci_state[ncci])
4661 {
4662 Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id;
4663 if (plci->tel) Id |= EXT_CONTROLLER;
4664 sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, data->Number,
4665 "ww", data->Handle, 0);
4666 }
4667 (ncci_ptr->data_out)++;
4668 if (ncci_ptr->data_out == MAX_DATA_B3)
4669 ncci_ptr->data_out = 0;
4670 (ncci_ptr->data_pending)--;
4671 }
4672 }
4673 }
4674}
4675
4676static void data_ack(PLCI *plci, byte ch)
4677{
4678 dword Id;
4679 DIVA_CAPI_ADAPTER *a;
4680 NCCI *ncci_ptr;
4681 word ncci;
4682
4683 a = plci->adapter;
4684 ncci = a->ch_ncci[ch];
4685 ncci_ptr = &(a->ncci[ncci]);
4686 if (ncci_ptr->data_ack_pending)
4687 {
4688 if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id))
4689 {
4690 Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id;
4691 if (plci->tel) Id |= EXT_CONTROLLER;
4692 sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, ncci_ptr->DataAck[ncci_ptr->data_ack_out].Number,
4693 "ww", ncci_ptr->DataAck[ncci_ptr->data_ack_out].Handle, 0);
4694 }
4695 (ncci_ptr->data_ack_out)++;
4696 if (ncci_ptr->data_ack_out == MAX_DATA_ACK)
4697 ncci_ptr->data_ack_out = 0;
4698 (ncci_ptr->data_ack_pending)--;
4699 }
4700}
4701
4702static void sig_ind(PLCI *plci)
4703{
4704 dword x_Id;
4705 dword Id;
4706 dword rId;
4707 word i;
4708 word cip;
4709 dword cip_mask;
4710 byte *ie;
4711 DIVA_CAPI_ADAPTER *a;
4712 API_PARSE saved_parms[MAX_MSG_PARMS + 1];
4713#define MAXPARMSIDS 31
4714 byte *parms[MAXPARMSIDS];
4715 byte *add_i[4];
4716 byte *multi_fac_parms[MAX_MULTI_IE];
4717 byte *multi_pi_parms[MAX_MULTI_IE];
4718 byte *multi_ssext_parms[MAX_MULTI_IE];
4719 byte *multi_CiPN_parms[MAX_MULTI_IE];
4720
4721 byte *multi_vswitch_parms[MAX_MULTI_IE];
4722
4723 byte ai_len;
4724 byte *esc_chi = "";
4725 byte *esc_law = "";
4726 byte *pty_cai = "";
4727 byte *esc_cr = "";
4728 byte *esc_profile = "";
4729
4730 byte facility[256];
4731 PLCI *tplci = NULL;
4732 byte chi[] = "\x02\x18\x01";
4733 byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08";
4734 byte resume_cau[] = "\x05\x05\x00\x02\x00\x00";
4735 /* ESC_MSGTYPE must be the last but one message, a new IE has to be */
4736 /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
4737 /* SMSG is situated at the end because its 0 (for compatibility reasons */
4738 /* (see Info_Mask Bit 4, first IE. then the message type) */
4739 static const word parms_id[] =
4740 {MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA,
4741 UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW,
4742 RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR,
4743 CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG};
4744 /* 14 FTY repl by ESC_CHI */
4745 /* 18 PI repl by ESC_LAW */
4746 /* removed OAD changed to 0xff for future use, OAD is multiIE now */
4747 static const word multi_fac_id[] = {1, FTY};
4748 static const word multi_pi_id[] = {1, PI};
4749 static const word multi_CiPN_id[] = {1, OAD};
4750 static const word multi_ssext_id[] = {1, ESC_SSEXT};
4751
4752 static const word multi_vswitch_id[] = {1, ESC_VSWITCH};
4753
4754 byte *cau;
4755 word ncci;
4756 byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
4757 byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
4758 byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
4759 byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00";
4760 byte force_mt_info = false;
4761 byte dir;
4762 dword d;
4763 word w;
4764
4765 a = plci->adapter;
4766 Id = ((word)plci->Id << 8) | a->Id;
4767 PUT_WORD(&SS_Ind[4], 0x0000);
4768
4769 if (plci->sig_remove_id)
4770 {
4771 plci->Sig.RNR = 2; /* discard */
4772 dbug(1, dprintf("SIG discard while remove pending"));
4773 return;
4774 }
4775 if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER;
4776 dbug(1, dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d",
4777 Id, plci->Id, plci->tel, plci->State, plci->channels, plci->hangup_flow_ctrl_timer));
4778 if (plci->Sig.Ind == CALL_HOLD_ACK && plci->channels)
4779 {
4780 plci->Sig.RNR = 1;
4781 return;
4782 }
4783 if (plci->Sig.Ind == HANGUP && plci->channels)
4784 {
4785 plci->Sig.RNR = 1;
4786 plci->hangup_flow_ctrl_timer++;
4787 /* recover the network layer after timeout */
4788 if (plci->hangup_flow_ctrl_timer == 100)
4789 {
4790 dbug(1, dprintf("Exceptional disc"));
4791 plci->Sig.RNR = 0;
4792 plci->hangup_flow_ctrl_timer = 0;
4793 for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
4794 {
4795 if (a->ncci_plci[ncci] == plci->Id)
4796 {
4797 cleanup_ncci_data(plci, ncci);
4798 if (plci->channels)plci->channels--;
4799 if (plci->appl)
4800 sendf(plci->appl, _DISCONNECT_B3_I, (((dword) ncci) << 16) | Id, 0, "ws", 0, "");
4801 }
4802 }
4803 if (plci->appl)
4804 sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
4805 plci_remove(plci);
4806 plci->State = IDLE;
4807 }
4808 return;
4809 }
4810
4811 /* do first parse the info with no OAD in, because OAD will be converted */
4812 /* first the multiple facility IE, then mult. progress ind. */
4813 /* then the parameters for the info_ind + conn_ind */
4814 IndParse(plci, multi_fac_id, multi_fac_parms, MAX_MULTI_IE);
4815 IndParse(plci, multi_pi_id, multi_pi_parms, MAX_MULTI_IE);
4816 IndParse(plci, multi_ssext_id, multi_ssext_parms, MAX_MULTI_IE);
4817
4818 IndParse(plci, multi_vswitch_id, multi_vswitch_parms, MAX_MULTI_IE);
4819
4820 IndParse(plci, parms_id, parms, 0);
4821 IndParse(plci, multi_CiPN_id, multi_CiPN_parms, MAX_MULTI_IE);
4822 esc_chi = parms[14];
4823 esc_law = parms[18];
4824 pty_cai = parms[24];
4825 esc_cr = parms[25];
4826 esc_profile = parms[27];
4827 if (esc_cr[0] && plci)
4828 {
4829 if (plci->cr_enquiry && plci->appl)
4830 {
4831 plci->cr_enquiry = false;
4832 /* d = MANU_ID */
4833 /* w = m_command */
4834 /* b = total length */
4835 /* b = indication type */
4836 /* b = length of all IEs */
4837 /* b = IE1 */
4838 /* S = IE1 length + cont. */
4839 /* b = IE2 */
4840 /* S = IE2 length + cont. */
4841 sendf(plci->appl,
4842 _MANUFACTURER_I,
4843 Id,
4844 0,
4845 "dwbbbbSbS", _DI_MANU_ID, plci->m_command,
4846 2 + 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], plci->Sig.Ind, 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], ESC, esc_cr, ESC, esc_law);
4847 }
4848 }
4849 /* create the additional info structure */
4850 add_i[1] = parms[15]; /* KEY of additional info */
4851 add_i[2] = parms[11]; /* UUI of additional info */
4852 ai_len = AddInfo(add_i, multi_fac_parms, esc_chi, facility);
4853
4854 /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card */
4855 /* indication returns by the card if requested by the function */
4856 /* AutomaticLaw() after driver init */
4857 if (a->automatic_law < 4)
4858 {
4859 if (esc_law[0]) {
4860 if (esc_law[2]) {
4861 dbug(0, dprintf("u-Law selected"));
4862 a->u_law = 1;
4863 }
4864 else {
4865 dbug(0, dprintf("a-Law selected"));
4866 a->u_law = 0;
4867 }
4868 a->automatic_law = 4;
4869 if (plci == a->automatic_lawPLCI) {
4870 plci->internal_command = 0;
4871 sig_req(plci, REMOVE, 0);
4872 send_req(plci);
4873 a->automatic_lawPLCI = NULL;
4874 }
4875 }
4876 if (esc_profile[0])
4877 {
4878 dbug(1, dprintf("[%06x] CardProfile: %lx %lx %lx %lx %lx",
4879 UnMapController(a->Id), GET_DWORD(&esc_profile[6]),
4880 GET_DWORD(&esc_profile[10]), GET_DWORD(&esc_profile[14]),
4881 GET_DWORD(&esc_profile[18]), GET_DWORD(&esc_profile[46])));
4882
4883 a->profile.Global_Options &= 0x000000ffL;
4884 a->profile.B1_Protocols &= 0x000003ffL;
4885 a->profile.B2_Protocols &= 0x00001fdfL;
4886 a->profile.B3_Protocols &= 0x000000b7L;
4887
4888 a->profile.Global_Options &= GET_DWORD(&esc_profile[6]) |
4889 GL_BCHANNEL_OPERATION_SUPPORTED;
4890 a->profile.B1_Protocols &= GET_DWORD(&esc_profile[10]);
4891 a->profile.B2_Protocols &= GET_DWORD(&esc_profile[14]);
4892 a->profile.B3_Protocols &= GET_DWORD(&esc_profile[18]);
4893 a->manufacturer_features = GET_DWORD(&esc_profile[46]);
4894 a->man_profile.private_options = 0;
4895
4896 if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER)
4897 {
4898 a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER;
4899 a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED;
4900 }
4901
4902
4903 if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP)
4904 a->man_profile.private_options |= 1L << PRIVATE_RTP;
4905 a->man_profile.rtp_primary_payloads = GET_DWORD(&esc_profile[50]);
4906 a->man_profile.rtp_additional_payloads = GET_DWORD(&esc_profile[54]);
4907
4908
4909 if (a->manufacturer_features & MANUFACTURER_FEATURE_T38)
4910 a->man_profile.private_options |= 1L << PRIVATE_T38;
4911
4912
4913 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD)
4914 a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
4915
4916
4917 if (a->manufacturer_features & MANUFACTURER_FEATURE_V18)
4918 a->man_profile.private_options |= 1L << PRIVATE_V18;
4919
4920
4921 if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE)
4922 a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE;
4923
4924
4925 if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS)
4926 a->man_profile.private_options |= 1L << PRIVATE_PIAFS;
4927
4928
4929 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
4930 a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS;
4931
4932
4933 if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN)
4934 a->man_profile.private_options |= 1L << PRIVATE_VOWN;
4935
4936
4937 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD)
4938 a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD;
4939
4940 }
4941 else
4942 {
4943 a->profile.Global_Options &= 0x0000007fL;
4944 a->profile.B1_Protocols &= 0x000003dfL;
4945 a->profile.B2_Protocols &= 0x00001adfL;
4946 a->profile.B3_Protocols &= 0x000000b7L;
4947 a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF;
4948 }
4949 if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF |
4950 MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
4951 {
4952 a->profile.Global_Options |= GL_DTMF_SUPPORTED;
4953 }
4954 a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL;
4955 dbug(1, dprintf("[%06x] Profile: %lx %lx %lx %lx %lx",
4956 UnMapController(a->Id), a->profile.Global_Options,
4957 a->profile.B1_Protocols, a->profile.B2_Protocols,
4958 a->profile.B3_Protocols, a->manufacturer_features));
4959 }
4960 /* codec plci for the handset/hook state support is just an internal id */
4961 if (plci != a->AdvCodecPLCI)
4962 {
4963 force_mt_info = SendMultiIE(plci, Id, multi_fac_parms, FTY, 0x20, 0);
4964 force_mt_info |= SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, 0);
4965 SendSSExtInd(NULL, plci, Id, multi_ssext_parms);
4966 SendInfo(plci, Id, parms, force_mt_info);
4967
4968 VSwitchReqInd(plci, Id, multi_vswitch_parms);
4969
4970 }
4971
4972 /* switch the codec to the b-channel */
4973 if (esc_chi[0] && plci && !plci->SuppState) {
4974 plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
4975 mixer_set_bchannel_id_esc(plci, plci->b_channel);
4976 dbug(1, dprintf("storeChannel=0x%x", plci->b_channel));
4977 if (plci->tel == ADV_VOICE && plci->appl) {
4978 SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
4979 }
4980 }
4981
4982 if (plci->appl) plci->appl->Number++;
4983
4984 switch (plci->Sig.Ind) {
4985 /* Response to Get_Supported_Services request */
4986 case S_SUPPORTED:
4987 dbug(1, dprintf("S_Supported"));
4988 if (!plci->appl) break;
4989 if (pty_cai[0] == 4)
4990 {
4991 PUT_DWORD(&CF_Ind[6], GET_DWORD(&pty_cai[1]));
4992 }
4993 else
4994 {
4995 PUT_DWORD(&CF_Ind[6], MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE);
4996 }
4997 PUT_WORD(&CF_Ind[1], 0);
4998 PUT_WORD(&CF_Ind[4], 0);
4999 sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7, plci->number, "wws", 0, 3, CF_Ind);
5000 plci_remove(plci);
5001 break;
5002
5003 /* Supplementary Service rejected */
5004 case S_SERVICE_REJ:
5005 dbug(1, dprintf("S_Reject=0x%x", pty_cai[5]));
5006 if (!pty_cai[0]) break;
5007 switch (pty_cai[5])
5008 {
5009 case ECT_EXECUTE:
5010 case THREE_PTY_END:
5011 case THREE_PTY_BEGIN:
5012 if (!plci->relatedPTYPLCI) break;
5013 tplci = plci->relatedPTYPLCI;
5014 rId = ((word)tplci->Id << 8) | tplci->adapter->Id;
5015 if (tplci->tel) rId |= EXT_CONTROLLER;
5016 if (pty_cai[5] == ECT_EXECUTE)
5017 {
5018 PUT_WORD(&SS_Ind[1], S_ECT);
5019
5020 plci->vswitchstate = 0;
5021 plci->relatedPTYPLCI->vswitchstate = 0;
5022
5023 }
5024 else
5025 {
5026 PUT_WORD(&SS_Ind[1], pty_cai[5] + 3);
5027 }
5028 if (pty_cai[2] != 0xff)
5029 {
5030 PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
5031 }
5032 else
5033 {
5034 PUT_WORD(&SS_Ind[4], 0x300E);
5035 }
5036 plci->relatedPTYPLCI = NULL;
5037 plci->ptyState = 0;
5038 sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
5039 break;
5040
5041 case CALL_DEFLECTION:
5042 if (pty_cai[2] != 0xff)
5043 {
5044 PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
5045 }
5046 else
5047 {
5048 PUT_WORD(&SS_Ind[4], 0x300E);
5049 }
5050 PUT_WORD(&SS_Ind[1], pty_cai[5]);
5051 for (i = 0; i < max_appl; i++)
5052 {
5053 if (application[i].CDEnable)
5054 {
5055 if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
5056 application[i].CDEnable = false;
5057 }
5058 }
5059 break;
5060
5061 case DEACTIVATION_DIVERSION:
5062 case ACTIVATION_DIVERSION:
5063 case DIVERSION_INTERROGATE_CFU:
5064 case DIVERSION_INTERROGATE_CFB:
5065 case DIVERSION_INTERROGATE_CFNR:
5066 case DIVERSION_INTERROGATE_NUM:
5067 case CCBS_REQUEST:
5068 case CCBS_DEACTIVATE:
5069 case CCBS_INTERROGATE:
5070 if (!plci->appl) break;
5071 if (pty_cai[2] != 0xff)
5072 {
5073 PUT_WORD(&Interr_Err_Ind[4], 0x3600 | (word)pty_cai[2]);
5074 }
5075 else
5076 {
5077 PUT_WORD(&Interr_Err_Ind[4], 0x300E);
5078 }
5079 switch (pty_cai[5])
5080 {
5081 case DEACTIVATION_DIVERSION:
5082 dbug(1, dprintf("Deact_Div"));
5083 Interr_Err_Ind[0] = 0x9;
5084 Interr_Err_Ind[3] = 0x6;
5085 PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_STOP);
5086 break;
5087 case ACTIVATION_DIVERSION:
5088 dbug(1, dprintf("Act_Div"));
5089 Interr_Err_Ind[0] = 0x9;
5090 Interr_Err_Ind[3] = 0x6;
5091 PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_START);
5092 break;
5093 case DIVERSION_INTERROGATE_CFU:
5094 case DIVERSION_INTERROGATE_CFB:
5095 case DIVERSION_INTERROGATE_CFNR:
5096 dbug(1, dprintf("Interr_Div"));
5097 Interr_Err_Ind[0] = 0xa;
5098 Interr_Err_Ind[3] = 0x7;
5099 PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_DIVERSION);
5100 break;
5101 case DIVERSION_INTERROGATE_NUM:
5102 dbug(1, dprintf("Interr_Num"));
5103 Interr_Err_Ind[0] = 0xa;
5104 Interr_Err_Ind[3] = 0x7;
5105 PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_NUMBERS);
5106 break;
5107 case CCBS_REQUEST:
5108 dbug(1, dprintf("CCBS Request"));
5109 Interr_Err_Ind[0] = 0xd;
5110 Interr_Err_Ind[3] = 0xa;
5111 PUT_WORD(&Interr_Err_Ind[1], S_CCBS_REQUEST);
5112 break;
5113 case CCBS_DEACTIVATE:
5114 dbug(1, dprintf("CCBS Deactivate"));
5115 Interr_Err_Ind[0] = 0x9;
5116 Interr_Err_Ind[3] = 0x6;
5117 PUT_WORD(&Interr_Err_Ind[1], S_CCBS_DEACTIVATE);
5118 break;
5119 case CCBS_INTERROGATE:
5120 dbug(1, dprintf("CCBS Interrogate"));
5121 Interr_Err_Ind[0] = 0xb;
5122 Interr_Err_Ind[3] = 0x8;
5123 PUT_WORD(&Interr_Err_Ind[1], S_CCBS_INTERROGATE);
5124 break;
5125 }
5126 PUT_DWORD(&Interr_Err_Ind[6], plci->appl->S_Handle);
5127 sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, Interr_Err_Ind);
5128 plci_remove(plci);
5129 break;
5130 case ACTIVATION_MWI:
5131 case DEACTIVATION_MWI:
5132 if (pty_cai[5] == ACTIVATION_MWI)
5133 {
5134 PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE);
5135 }
5136 else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE);
5137
5138 if (pty_cai[2] != 0xff)
5139 {
5140 PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
5141 }
5142 else
5143 {
5144 PUT_WORD(&SS_Ind[4], 0x300E);
5145 }
5146
5147 if (plci->cr_enquiry)
5148 {
5149 sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind);
5150 plci_remove(plci);
5151 }
5152 else
5153 {
5154 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
5155 }
5156 break;
5157 case CONF_ADD: /* ERROR */
5158 case CONF_BEGIN:
5159 case CONF_DROP:
5160 case CONF_ISOLATE:
5161 case CONF_REATTACH:
5162 CONF_Ind[0] = 9;
5163 CONF_Ind[3] = 6;
5164 switch (pty_cai[5])
5165 {
5166 case CONF_BEGIN:
5167 PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN);
5168 plci->ptyState = 0;
5169 break;
5170 case CONF_DROP:
5171 CONF_Ind[0] = 5;
5172 CONF_Ind[3] = 2;
5173 PUT_WORD(&CONF_Ind[1], S_CONF_DROP);
5174 plci->ptyState = CONNECTED;
5175 break;
5176 case CONF_ISOLATE:
5177 CONF_Ind[0] = 5;
5178 CONF_Ind[3] = 2;
5179 PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE);
5180 plci->ptyState = CONNECTED;
5181 break;
5182 case CONF_REATTACH:
5183 CONF_Ind[0] = 5;
5184 CONF_Ind[3] = 2;
5185 PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH);
5186 plci->ptyState = CONNECTED;
5187 break;
5188 case CONF_ADD:
5189 PUT_WORD(&CONF_Ind[1], S_CONF_ADD);
5190 plci->relatedPTYPLCI = NULL;
5191 tplci = plci->relatedPTYPLCI;
5192 if (tplci) tplci->ptyState = CONNECTED;
5193 plci->ptyState = CONNECTED;
5194 break;
5195 }
5196
5197 if (pty_cai[2] != 0xff)
5198 {
5199 PUT_WORD(&CONF_Ind[4], 0x3600 | (word)pty_cai[2]);
5200 }
5201 else
5202 {
5203 PUT_WORD(&CONF_Ind[4], 0x3303); /* Time-out: network did not respond
5204 within the required time */
5205 }
5206
5207 PUT_DWORD(&CONF_Ind[6], 0x0);
5208 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
5209 break;
5210 }
5211 break;
5212
5213 /* Supplementary Service indicates success */
5214 case S_SERVICE:
5215 dbug(1, dprintf("Service_Ind"));
5216 PUT_WORD(&CF_Ind[4], 0);
5217 switch (pty_cai[5])
5218 {
5219 case THREE_PTY_END:
5220 case THREE_PTY_BEGIN:
5221 case ECT_EXECUTE:
5222 if (!plci->relatedPTYPLCI) break;
5223 tplci = plci->relatedPTYPLCI;
5224 rId = ((word)tplci->Id << 8) | tplci->adapter->Id;
5225 if (tplci->tel) rId |= EXT_CONTROLLER;
5226 if (pty_cai[5] == ECT_EXECUTE)
5227 {
5228 PUT_WORD(&SS_Ind[1], S_ECT);
5229
5230 if (plci->vswitchstate != 3)
5231 {
5232
5233 plci->ptyState = IDLE;
5234 plci->relatedPTYPLCI = NULL;
5235 plci->ptyState = 0;
5236
5237 }
5238
5239 dbug(1, dprintf("ECT OK"));
5240 sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
5241
5242
5243
5244 }
5245 else
5246 {
5247 switch (plci->ptyState)
5248 {
5249 case S_3PTY_BEGIN:
5250 plci->ptyState = CONNECTED;
5251 dbug(1, dprintf("3PTY ON"));
5252 break;
5253
5254 case S_3PTY_END:
5255 plci->ptyState = IDLE;
5256 plci->relatedPTYPLCI = NULL;
5257 plci->ptyState = 0;
5258 dbug(1, dprintf("3PTY OFF"));
5259 break;
5260 }
5261 PUT_WORD(&SS_Ind[1], pty_cai[5] + 3);
5262 sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
5263 }
5264 break;
5265
5266 case CALL_DEFLECTION:
5267 PUT_WORD(&SS_Ind[1], pty_cai[5]);
5268 for (i = 0; i < max_appl; i++)
5269 {
5270 if (application[i].CDEnable)
5271 {
5272 if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
5273 application[i].CDEnable = false;
5274 }
5275 }
5276 break;
5277
5278 case DEACTIVATION_DIVERSION:
5279 case ACTIVATION_DIVERSION:
5280 if (!plci->appl) break;
5281 PUT_WORD(&CF_Ind[1], pty_cai[5] + 2);
5282 PUT_DWORD(&CF_Ind[6], plci->appl->S_Handle);
5283 sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, CF_Ind);
5284 plci_remove(plci);
5285 break;
5286
5287 case DIVERSION_INTERROGATE_CFU:
5288 case DIVERSION_INTERROGATE_CFB:
5289 case DIVERSION_INTERROGATE_CFNR:
5290 case DIVERSION_INTERROGATE_NUM:
5291 case CCBS_REQUEST:
5292 case CCBS_DEACTIVATE:
5293 case CCBS_INTERROGATE:
5294 if (!plci->appl) break;
5295 switch (pty_cai[5])
5296 {
5297 case DIVERSION_INTERROGATE_CFU:
5298 case DIVERSION_INTERROGATE_CFB:
5299 case DIVERSION_INTERROGATE_CFNR:
5300 dbug(1, dprintf("Interr_Div"));
5301 PUT_WORD(&pty_cai[1], S_INTERROGATE_DIVERSION);
5302 pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
5303 break;
5304 case DIVERSION_INTERROGATE_NUM:
5305 dbug(1, dprintf("Interr_Num"));
5306 PUT_WORD(&pty_cai[1], S_INTERROGATE_NUMBERS);
5307 pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
5308 break;
5309 case CCBS_REQUEST:
5310 dbug(1, dprintf("CCBS Request"));
5311 PUT_WORD(&pty_cai[1], S_CCBS_REQUEST);
5312 pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
5313 break;
5314 case CCBS_DEACTIVATE:
5315 dbug(1, dprintf("CCBS Deactivate"));
5316 PUT_WORD(&pty_cai[1], S_CCBS_DEACTIVATE);
5317 pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
5318 break;
5319 case CCBS_INTERROGATE:
5320 dbug(1, dprintf("CCBS Interrogate"));
5321 PUT_WORD(&pty_cai[1], S_CCBS_INTERROGATE);
5322 pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
5323 break;
5324 }
5325 PUT_WORD(&pty_cai[4], 0); /* Supplementary Service Reason */
5326 PUT_DWORD(&pty_cai[6], plci->appl->S_Handle);
5327 sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "wS", 3, pty_cai);
5328 plci_remove(plci);
5329 break;
5330
5331 case ACTIVATION_MWI:
5332 case DEACTIVATION_MWI:
5333 if (pty_cai[5] == ACTIVATION_MWI)
5334 {
5335 PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE);
5336 }
5337 else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE);
5338 if (plci->cr_enquiry)
5339 {
5340 sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind);
5341 plci_remove(plci);
5342 }
5343 else
5344 {
5345 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
5346 }
5347 break;
5348 case MWI_INDICATION:
5349 if (pty_cai[0] >= 0x12)
5350 {
5351 PUT_WORD(&pty_cai[3], S_MWI_INDICATE);
5352 pty_cai[2] = pty_cai[0] - 2; /* len Parameter */
5353 pty_cai[5] = pty_cai[0] - 5; /* Supplementary Service-specific parameter len */
5354 if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_MWI))
5355 {
5356 if (plci->internal_command == GET_MWI_STATE) /* result on Message Waiting Listen */
5357 {
5358 sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "wS", 3, &pty_cai[2]);
5359 plci_remove(plci);
5360 return;
5361 }
5362 else sendf(plci->appl, _FACILITY_I, Id, 0, "wS", 3, &pty_cai[2]);
5363 pty_cai[0] = 0;
5364 }
5365 else
5366 {
5367 for (i = 0; i < max_appl; i++)
5368 {
5369 if (a->Notification_Mask[i]&SMASK_MWI)
5370 {
5371 sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "wS", 3, &pty_cai[2]);
5372 pty_cai[0] = 0;
5373 }
5374 }
5375 }
5376
5377 if (!pty_cai[0])
5378 { /* acknowledge */
5379 facility[2] = 0; /* returncode */
5380 }
5381 else facility[2] = 0xff;
5382 }
5383 else
5384 {
5385 /* reject */
5386 facility[2] = 0xff; /* returncode */
5387 }
5388 facility[0] = 2;
5389 facility[1] = MWI_RESPONSE; /* Function */
5390 add_p(plci, CAI, facility);
5391 add_p(plci, ESC, multi_ssext_parms[0]); /* remembered parameter -> only one possible */
5392 sig_req(plci, S_SERVICE, 0);
5393 send_req(plci);
5394 plci->command = 0;
5395 next_internal_command(Id, plci);
5396 break;
5397 case CONF_ADD: /* OK */
5398 case CONF_BEGIN:
5399 case CONF_DROP:
5400 case CONF_ISOLATE:
5401 case CONF_REATTACH:
5402 case CONF_PARTYDISC:
5403 CONF_Ind[0] = 9;
5404 CONF_Ind[3] = 6;
5405 switch (pty_cai[5])
5406 {
5407 case CONF_BEGIN:
5408 PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN);
5409 if (pty_cai[0] == 6)
5410 {
5411 d = pty_cai[6];
5412 PUT_DWORD(&CONF_Ind[6], d); /* PartyID */
5413 }
5414 else
5415 {
5416 PUT_DWORD(&CONF_Ind[6], 0x0);
5417 }
5418 break;
5419 case CONF_ISOLATE:
5420 PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE);
5421 CONF_Ind[0] = 5;
5422 CONF_Ind[3] = 2;
5423 break;
5424 case CONF_REATTACH:
5425 PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH);
5426 CONF_Ind[0] = 5;
5427 CONF_Ind[3] = 2;
5428 break;
5429 case CONF_DROP:
5430 PUT_WORD(&CONF_Ind[1], S_CONF_DROP);
5431 CONF_Ind[0] = 5;
5432 CONF_Ind[3] = 2;
5433 break;
5434 case CONF_ADD:
5435 PUT_WORD(&CONF_Ind[1], S_CONF_ADD);
5436 d = pty_cai[6];
5437 PUT_DWORD(&CONF_Ind[6], d); /* PartyID */
5438 tplci = plci->relatedPTYPLCI;
5439 if (tplci) tplci->ptyState = CONNECTED;
5440 break;
5441 case CONF_PARTYDISC:
5442 CONF_Ind[0] = 7;
5443 CONF_Ind[3] = 4;
5444 PUT_WORD(&CONF_Ind[1], S_CONF_PARTYDISC);
5445 d = pty_cai[6];
5446 PUT_DWORD(&CONF_Ind[4], d); /* PartyID */
5447 break;
5448 }
5449 plci->ptyState = CONNECTED;
5450 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
5451 break;
5452 case CCBS_INFO_RETAIN:
5453 case CCBS_ERASECALLLINKAGEID:
5454 case CCBS_STOP_ALERTING:
5455 CONF_Ind[0] = 5;
5456 CONF_Ind[3] = 2;
5457 switch (pty_cai[5])
5458 {
5459 case CCBS_INFO_RETAIN:
5460 PUT_WORD(&CONF_Ind[1], S_CCBS_INFO_RETAIN);
5461 break;
5462 case CCBS_STOP_ALERTING:
5463 PUT_WORD(&CONF_Ind[1], S_CCBS_STOP_ALERTING);
5464 break;
5465 case CCBS_ERASECALLLINKAGEID:
5466 PUT_WORD(&CONF_Ind[1], S_CCBS_ERASECALLLINKAGEID);
5467 CONF_Ind[0] = 7;
5468 CONF_Ind[3] = 4;
5469 CONF_Ind[6] = 0;
5470 CONF_Ind[7] = 0;
5471 break;
5472 }
5473 w = pty_cai[6];
5474 PUT_WORD(&CONF_Ind[4], w); /* PartyID */
5475
5476 if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_CCBS))
5477 {
5478 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
5479 }
5480 else
5481 {
5482 for (i = 0; i < max_appl; i++)
5483 if (a->Notification_Mask[i] & SMASK_CCBS)
5484 sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "ws", 3, CONF_Ind);
5485 }
5486 break;
5487 }
5488 break;
5489 case CALL_HOLD_REJ:
5490 cau = parms[7];
5491 if (cau)
5492 {
5493 i = _L3_CAUSE | cau[2];
5494 if (cau[2] == 0) i = 0x3603;
5495 }
5496 else
5497 {
5498 i = 0x3603;
5499 }
5500 PUT_WORD(&SS_Ind[1], S_HOLD);
5501 PUT_WORD(&SS_Ind[4], i);
5502 if (plci->SuppState == HOLD_REQUEST)
5503 {
5504 plci->SuppState = IDLE;
5505 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
5506 }
5507 break;
5508
5509 case CALL_HOLD_ACK:
5510 if (plci->SuppState == HOLD_REQUEST)
5511 {
5512 plci->SuppState = CALL_HELD;
5513 CodecIdCheck(a, plci);
5514 start_internal_command(Id, plci, hold_save_command);
5515 }
5516 break;
5517
5518 case CALL_RETRIEVE_REJ:
5519 cau = parms[7];
5520 if (cau)
5521 {
5522 i = _L3_CAUSE | cau[2];
5523 if (cau[2] == 0) i = 0x3603;
5524 }
5525 else
5526 {
5527 i = 0x3603;
5528 }
5529 PUT_WORD(&SS_Ind[1], S_RETRIEVE);
5530 PUT_WORD(&SS_Ind[4], i);
5531 if (plci->SuppState == RETRIEVE_REQUEST)
5532 {
5533 plci->SuppState = CALL_HELD;
5534 CodecIdCheck(a, plci);
5535 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
5536 }
5537 break;
5538
5539 case CALL_RETRIEVE_ACK:
5540 PUT_WORD(&SS_Ind[1], S_RETRIEVE);
5541 if (plci->SuppState == RETRIEVE_REQUEST)
5542 {
5543 plci->SuppState = IDLE;
5544 plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
5545 plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
5546 if (plci->tel)
5547 {
5548 mixer_set_bchannel_id_esc(plci, plci->b_channel);
5549 dbug(1, dprintf("RetrChannel=0x%x", plci->b_channel));
5550 SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
5551 if (plci->B2_prot == B2_TRANSPARENT && plci->B3_prot == B3_TRANSPARENT)
5552 {
5553 dbug(1, dprintf("Get B-ch"));
5554 start_internal_command(Id, plci, retrieve_restore_command);
5555 }
5556 else
5557 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
5558 }
5559 else
5560 start_internal_command(Id, plci, retrieve_restore_command);
5561 }
5562 break;
5563
5564 case INDICATE_IND:
5565 if (plci->State != LISTENING) {
5566 sig_req(plci, HANGUP, 0);
5567 send_req(plci);
5568 break;
5569 }
5570 cip = find_cip(a, parms[4], parms[6]);
5571 cip_mask = 1L << cip;
5572 dbug(1, dprintf("cip=%d,cip_mask=%lx", cip, cip_mask));
5573 bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
5574 if (!remove_started && !a->adapter_disabled)
5575 {
5576 group_optimization(a, plci);
5577 for_each_set_bit(i, plci->group_optimization_mask_table, max_appl) {
5578 if (application[i].Id
5579 && (a->CIP_Mask[i] & 1 || a->CIP_Mask[i] & cip_mask)
5580 && CPN_filter_ok(parms[0], a, i)) {
5581 dbug(1, dprintf("storedcip_mask[%d]=0x%lx", i, a->CIP_Mask[i]));
5582 __set_bit(i, plci->c_ind_mask_table);
5583 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
5584 plci->State = INC_CON_PENDING;
5585 plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) |
5586 CALL_DIR_IN | CALL_DIR_ANSWER;
5587 if (esc_chi[0]) {
5588 plci->b_channel = esc_chi[esc_chi[0]] & 0x1f;
5589 mixer_set_bchannel_id_esc(plci, plci->b_channel);
5590 }
5591 /* if a listen on the ext controller is done, check if hook states */
5592 /* are supported or if just a on board codec must be activated */
5593 if (a->codec_listen[i] && !a->AdvSignalPLCI) {
5594 if (a->profile.Global_Options & HANDSET)
5595 plci->tel = ADV_VOICE;
5596 else if (a->profile.Global_Options & ON_BOARD_CODEC)
5597 plci->tel = CODEC;
5598 if (plci->tel) Id |= EXT_CONTROLLER;
5599 a->codec_listen[i] = plci;
5600 }
5601
5602 sendf(&application[i], _CONNECT_I, Id, 0,
5603 "wSSSSSSSbSSSSS", cip, /* CIP */
5604 parms[0], /* CalledPartyNumber */
5605 multi_CiPN_parms[0], /* CallingPartyNumber */
5606 parms[2], /* CalledPartySubad */
5607 parms[3], /* CallingPartySubad */
5608 parms[4], /* BearerCapability */
5609 parms[5], /* LowLC */
5610 parms[6], /* HighLC */
5611 ai_len, /* nested struct add_i */
5612 add_i[0], /* B channel info */
5613 add_i[1], /* keypad facility */
5614 add_i[2], /* user user data */
5615 add_i[3], /* nested facility */
5616 multi_CiPN_parms[1] /* second CiPN(SCR) */
5617 );
5618 SendSSExtInd(&application[i],
5619 plci,
5620 Id,
5621 multi_ssext_parms);
5622 SendSetupInfo(&application[i],
5623 plci,
5624 Id,
5625 parms,
5626 SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, true));
5627 }
5628 }
5629 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
5630 }
5631 if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL)) {
5632 sig_req(plci, HANGUP, 0);
5633 send_req(plci);
5634 plci->State = IDLE;
5635 }
5636 plci->notifiedcall = 0;
5637 a->listen_active--;
5638 listen_check(a);
5639 break;
5640
5641 case CALL_PEND_NOTIFY:
5642 plci->notifiedcall = 1;
5643 listen_check(a);
5644 break;
5645
5646 case CALL_IND:
5647 case CALL_CON:
5648 if (plci->State == ADVANCED_VOICE_SIG || plci->State == ADVANCED_VOICE_NOSIG)
5649 {
5650 if (plci->internal_command == PERM_COD_CONN_PEND)
5651 {
5652 if (plci->State == ADVANCED_VOICE_NOSIG)
5653 {
5654 dbug(1, dprintf("***Codec OK"));
5655 if (a->AdvSignalPLCI)
5656 {
5657 tplci = a->AdvSignalPLCI;
5658 if (tplci->spoofed_msg)
5659 {
5660 dbug(1, dprintf("***Spoofed Msg(0x%x)", tplci->spoofed_msg));
5661 tplci->command = 0;
5662 tplci->internal_command = 0;
5663 x_Id = ((word)tplci->Id << 8) | tplci->adapter->Id | 0x80;
5664 switch (tplci->spoofed_msg)
5665 {
5666 case CALL_RES:
5667 tplci->command = _CONNECT_I | RESPONSE;
5668 api_load_msg(&tplci->saved_msg, saved_parms);
5669 add_b1(tplci, &saved_parms[1], 0, tplci->B1_facilities);
5670 if (tplci->adapter->Info_Mask[tplci->appl->Id - 1] & 0x200)
5671 {
5672 /* early B3 connect (CIP mask bit 9) no release after a disc */
5673 add_p(tplci, LLI, "\x01\x01");
5674 }
5675 add_s(tplci, CONN_NR, &saved_parms[2]);
5676 add_s(tplci, LLC, &saved_parms[4]);
5677 add_ai(tplci, &saved_parms[5]);
5678 tplci->State = INC_CON_ACCEPT;
5679 sig_req(tplci, CALL_RES, 0);
5680 send_req(tplci);
5681 break;
5682
5683 case AWAITING_SELECT_B:
5684 dbug(1, dprintf("Select_B continue"));
5685 start_internal_command(x_Id, tplci, select_b_command);
5686 break;
5687
5688 case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */
5689 if (!tplci->Sig.Id)
5690 {
5691 dbug(1, dprintf("No SigID!"));
5692 sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI);
5693 plci_remove(tplci);
5694 break;
5695 }
5696 tplci->command = _MANUFACTURER_R;
5697 api_load_msg(&tplci->saved_msg, saved_parms);
5698 dir = saved_parms[2].info[0];
5699 if (dir == 1) {
5700 sig_req(tplci, CALL_REQ, 0);
5701 }
5702 else if (!dir) {
5703 sig_req(tplci, LISTEN_REQ, 0);
5704 }
5705 send_req(tplci);
5706 sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, 0);
5707 break;
5708
5709 case (CALL_REQ | AWAITING_MANUF_CON):
5710 sig_req(tplci, CALL_REQ, 0);
5711 send_req(tplci);
5712 break;
5713
5714 case CALL_REQ:
5715 if (!tplci->Sig.Id)
5716 {
5717 dbug(1, dprintf("No SigID!"));
5718 sendf(tplci->appl, _CONNECT_R | CONFIRM, tplci->adapter->Id, 0, "w", _OUT_OF_PLCI);
5719 plci_remove(tplci);
5720 break;
5721 }
5722 tplci->command = _CONNECT_R;
5723 api_load_msg(&tplci->saved_msg, saved_parms);
5724 add_s(tplci, CPN, &saved_parms[1]);
5725 add_s(tplci, DSA, &saved_parms[3]);
5726 add_ai(tplci, &saved_parms[9]);
5727 sig_req(tplci, CALL_REQ, 0);
5728 send_req(tplci);
5729 break;
5730
5731 case CALL_RETRIEVE:
5732 tplci->command = C_RETRIEVE_REQ;
5733 sig_req(tplci, CALL_RETRIEVE, 0);
5734 send_req(tplci);
5735 break;
5736 }
5737 tplci->spoofed_msg = 0;
5738 if (tplci->internal_command == 0)
5739 next_internal_command(x_Id, tplci);
5740 }
5741 }
5742 next_internal_command(Id, plci);
5743 break;
5744 }
5745 dbug(1, dprintf("***Codec Hook Init Req"));
5746 plci->internal_command = PERM_COD_HOOK;
5747 add_p(plci, FTY, "\x01\x09"); /* Get Hook State*/
5748 sig_req(plci, TEL_CTRL, 0);
5749 send_req(plci);
5750 }
5751 }
5752 else if (plci->command != _MANUFACTURER_R /* old style permanent connect */
5753 && plci->State != INC_ACT_PENDING)
5754 {
5755 mixer_set_bchannel_id_esc(plci, plci->b_channel);
5756 if (plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */
5757 {
5758 chi[2] = plci->b_channel;
5759 SetVoiceChannel(a->AdvCodecPLCI, chi, a);
5760 }
5761 sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "Sss", parms[21], "", "");
5762 plci->State = INC_ACT_PENDING;
5763 }
5764 break;
5765
5766 case TEL_CTRL:
5767 ie = multi_fac_parms[0]; /* inspect the facility hook indications */
5768 if (plci->State == ADVANCED_VOICE_SIG && ie[0]) {
5769 switch (ie[1] & 0x91) {
5770 case 0x80: /* hook off */
5771 case 0x81:
5772 if (plci->internal_command == PERM_COD_HOOK)
5773 {
5774 dbug(1, dprintf("init:hook_off"));
5775 plci->hook_state = ie[1];
5776 next_internal_command(Id, plci);
5777 break;
5778 }
5779 else /* ignore doubled hook indications */
5780 {
5781 if (((plci->hook_state) & 0xf0) == 0x80)
5782 {
5783 dbug(1, dprintf("ignore hook"));
5784 break;
5785 }
5786 plci->hook_state = ie[1]&0x91;
5787 }
5788 /* check for incoming call pending */
5789 /* and signal '+'.Appl must decide */
5790 /* with connect_res if call must */
5791 /* accepted or not */
5792 for (i = 0, tplci = NULL; i < max_appl; i++) {
5793 if (a->codec_listen[i]
5794 && (a->codec_listen[i]->State == INC_CON_PENDING
5795 || a->codec_listen[i]->State == INC_CON_ALERT)) {
5796 tplci = a->codec_listen[i];
5797 tplci->appl = &application[i];
5798 }
5799 }
5800 /* no incoming call, do outgoing call */
5801 /* and signal '+' if outg. setup */
5802 if (!a->AdvSignalPLCI && !tplci) {
5803 if ((i = get_plci(a))) {
5804 a->AdvSignalPLCI = &a->plci[i - 1];
5805 tplci = a->AdvSignalPLCI;
5806 tplci->tel = ADV_VOICE;
5807 PUT_WORD(&voice_cai[5], a->AdvSignalAppl->MaxDataLength);
5808 if (a->Info_Mask[a->AdvSignalAppl->Id - 1] & 0x200) {
5809 /* early B3 connect (CIP mask bit 9) no release after a disc */
5810 add_p(tplci, LLI, "\x01\x01");
5811 }
5812 add_p(tplci, CAI, voice_cai);
5813 add_p(tplci, OAD, a->TelOAD);
5814 add_p(tplci, OSA, a->TelOSA);
5815 add_p(tplci, SHIFT | 6, NULL);
5816 add_p(tplci, SIN, "\x02\x01\x00");
5817 add_p(tplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
5818 sig_req(tplci, ASSIGN, DSIG_ID);
5819 a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ;
5820 a->AdvSignalPLCI->command = 0;
5821 tplci->appl = a->AdvSignalAppl;
5822 tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
5823 send_req(tplci);
5824 }
5825
5826 }
5827
5828 if (!tplci) break;
5829 Id = ((word)tplci->Id << 8) | a->Id;
5830 Id |= EXT_CONTROLLER;
5831 sendf(tplci->appl,
5832 _FACILITY_I,
5833 Id,
5834 0,
5835 "ws", (word)0, "\x01+");
5836 break;
5837
5838 case 0x90: /* hook on */
5839 case 0x91:
5840 if (plci->internal_command == PERM_COD_HOOK)
5841 {
5842 dbug(1, dprintf("init:hook_on"));
5843 plci->hook_state = ie[1] & 0x91;
5844 next_internal_command(Id, plci);
5845 break;
5846 }
5847 else /* ignore doubled hook indications */
5848 {
5849 if (((plci->hook_state) & 0xf0) == 0x90) break;
5850 plci->hook_state = ie[1] & 0x91;
5851 }
5852 /* hangup the adv. voice call and signal '-' to the appl */
5853 if (a->AdvSignalPLCI) {
5854 Id = ((word)a->AdvSignalPLCI->Id << 8) | a->Id;
5855 if (plci->tel) Id |= EXT_CONTROLLER;
5856 sendf(a->AdvSignalAppl,
5857 _FACILITY_I,
5858 Id,
5859 0,
5860 "ws", (word)0, "\x01-");
5861 a->AdvSignalPLCI->internal_command = HOOK_ON_REQ;
5862 a->AdvSignalPLCI->command = 0;
5863 sig_req(a->AdvSignalPLCI, HANGUP, 0);
5864 send_req(a->AdvSignalPLCI);
5865 }
5866 break;
5867 }
5868 }
5869 break;
5870
5871 case RESUME:
5872 __clear_bit(plci->appl->Id - 1, plci->c_ind_mask_table);
5873 PUT_WORD(&resume_cau[4], GOOD);
5874 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau);
5875 break;
5876
5877 case SUSPEND:
5878 bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
5879
5880 if (plci->NL.Id && !plci->nl_remove_id) {
5881 mixer_remove(plci);
5882 nl_req_ncci(plci, REMOVE, 0);
5883 }
5884 if (!plci->sig_remove_id) {
5885 plci->internal_command = 0;
5886 sig_req(plci, REMOVE, 0);
5887 }
5888 send_req(plci);
5889 if (!plci->channels) {
5890 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, "\x05\x04\x00\x02\x00\x00");
5891 sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
5892 }
5893 break;
5894
5895 case SUSPEND_REJ:
5896 break;
5897
5898 case HANGUP:
5899 plci->hangup_flow_ctrl_timer = 0;
5900 if (plci->manufacturer && plci->State == LOCAL_CONNECT) break;
5901 cau = parms[7];
5902 if (cau) {
5903 i = _L3_CAUSE | cau[2];
5904 if (cau[2] == 0) i = 0;
5905 else if (cau[2] == 8) i = _L1_ERROR;
5906 else if (cau[2] == 9 || cau[2] == 10) i = _L2_ERROR;
5907 else if (cau[2] == 5) i = _CAPI_GUARD_ERROR;
5908 }
5909 else {
5910 i = _L3_ERROR;
5911 }
5912
5913 if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
5914 {
5915 for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
5916 sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
5917 }
5918 else
5919 {
5920 bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
5921 }
5922 if (!plci->appl)
5923 {
5924 if (plci->State == LISTENING)
5925 {
5926 plci->notifiedcall = 0;
5927 a->listen_active--;
5928 }
5929 plci->State = INC_DIS_PENDING;
5930 if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
5931 {
5932 plci->State = IDLE;
5933 if (plci->NL.Id && !plci->nl_remove_id)
5934 {
5935 mixer_remove(plci);
5936 nl_req_ncci(plci, REMOVE, 0);
5937 }
5938 if (!plci->sig_remove_id)
5939 {
5940 plci->internal_command = 0;
5941 sig_req(plci, REMOVE, 0);
5942 }
5943 send_req(plci);
5944 }
5945 }
5946 else
5947 {
5948 /* collision of DISCONNECT or CONNECT_RES with HANGUP can */
5949 /* result in a second HANGUP! Don't generate another */
5950 /* DISCONNECT */
5951 if (plci->State != IDLE && plci->State != INC_DIS_PENDING)
5952 {
5953 if (plci->State == RESUMING)
5954 {
5955 PUT_WORD(&resume_cau[4], i);
5956 sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau);
5957 }
5958 plci->State = INC_DIS_PENDING;
5959 sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", i);
5960 }
5961 }
5962 break;
5963
5964 case SSEXT_IND:
5965 SendSSExtInd(NULL, plci, Id, multi_ssext_parms);
5966 break;
5967
5968 case VSWITCH_REQ:
5969 VSwitchReqInd(plci, Id, multi_vswitch_parms);
5970 break;
5971 case VSWITCH_IND:
5972 if (plci->relatedPTYPLCI &&
5973 plci->vswitchstate == 3 &&
5974 plci->relatedPTYPLCI->vswitchstate == 3 &&
5975 parms[MAXPARMSIDS - 1][0])
5976 {
5977 add_p(plci->relatedPTYPLCI, SMSG, parms[MAXPARMSIDS - 1]);
5978 sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
5979 send_req(plci->relatedPTYPLCI);
5980 }
5981 else VSwitchReqInd(plci, Id, multi_vswitch_parms);
5982 break;
5983
5984 }
5985}
5986
5987
5988static void SendSetupInfo(APPL *appl, PLCI *plci, dword Id, byte **parms, byte Info_Sent_Flag)
5989{
5990 word i;
5991 byte *ie;
5992 word Info_Number;
5993 byte *Info_Element;
5994 word Info_Mask = 0;
5995
5996 dbug(1, dprintf("SetupInfo"));
5997
5998 for (i = 0; i < MAXPARMSIDS; i++) {
5999 ie = parms[i];
6000 Info_Number = 0;
6001 Info_Element = ie;
6002 if (ie[0]) {
6003 switch (i) {
6004 case 0:
6005 dbug(1, dprintf("CPN "));
6006 Info_Number = 0x0070;
6007 Info_Mask = 0x80;
6008 Info_Sent_Flag = true;
6009 break;
6010 case 8: /* display */
6011 dbug(1, dprintf("display(%d)", i));
6012 Info_Number = 0x0028;
6013 Info_Mask = 0x04;
6014 Info_Sent_Flag = true;
6015 break;
6016 case 16: /* Channel Id */
6017 dbug(1, dprintf("CHI"));
6018 Info_Number = 0x0018;
6019 Info_Mask = 0x100;
6020 Info_Sent_Flag = true;
6021 mixer_set_bchannel_id(plci, Info_Element);
6022 break;
6023 case 19: /* Redirected Number */
6024 dbug(1, dprintf("RDN"));
6025 Info_Number = 0x0074;
6026 Info_Mask = 0x400;
6027 Info_Sent_Flag = true;
6028 break;
6029 case 20: /* Redirected Number extended */
6030 dbug(1, dprintf("RDX"));
6031 Info_Number = 0x0073;
6032 Info_Mask = 0x400;
6033 Info_Sent_Flag = true;
6034 break;
6035 case 22: /* Redirecing Number */
6036 dbug(1, dprintf("RIN"));
6037 Info_Number = 0x0076;
6038 Info_Mask = 0x400;
6039 Info_Sent_Flag = true;
6040 break;
6041 default:
6042 Info_Number = 0;
6043 break;
6044 }
6045 }
6046
6047 if (i == MAXPARMSIDS - 2) { /* to indicate the message type "Setup" */
6048 Info_Number = 0x8000 | 5;
6049 Info_Mask = 0x10;
6050 Info_Element = "";
6051 }
6052
6053 if (Info_Sent_Flag && Info_Number) {
6054 if (plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask) {
6055 sendf(appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
6056 }
6057 }
6058 }
6059}
6060
6061
6062static void SendInfo(PLCI *plci, dword Id, byte **parms, byte iesent)
6063{
6064 word i;
6065 word j;
6066 word k;
6067 byte *ie;
6068 word Info_Number;
6069 byte *Info_Element;
6070 word Info_Mask = 0;
6071 static byte charges[5] = {4, 0, 0, 0, 0};
6072 static byte cause[] = {0x02, 0x80, 0x00};
6073 APPL *appl;
6074
6075 dbug(1, dprintf("InfoParse "));
6076
6077 if (
6078 !plci->appl
6079 && !plci->State
6080 && plci->Sig.Ind != NCR_FACILITY
6081 )
6082 {
6083 dbug(1, dprintf("NoParse "));
6084 return;
6085 }
6086 cause[2] = 0;
6087 for (i = 0; i < MAXPARMSIDS; i++) {
6088 ie = parms[i];
6089 Info_Number = 0;
6090 Info_Element = ie;
6091 if (ie[0]) {
6092 switch (i) {
6093 case 0:
6094 dbug(1, dprintf("CPN "));
6095 Info_Number = 0x0070;
6096 Info_Mask = 0x80;
6097 break;
6098 case 7: /* ESC_CAU */
6099 dbug(1, dprintf("cau(0x%x)", ie[2]));
6100 Info_Number = 0x0008;
6101 Info_Mask = 0x00;
6102 cause[2] = ie[2];
6103 Info_Element = NULL;
6104 break;
6105 case 8: /* display */
6106 dbug(1, dprintf("display(%d)", i));
6107 Info_Number = 0x0028;
6108 Info_Mask = 0x04;
6109 break;
6110 case 9: /* Date display */
6111 dbug(1, dprintf("date(%d)", i));
6112 Info_Number = 0x0029;
6113 Info_Mask = 0x02;
6114 break;
6115 case 10: /* charges */
6116 for (j = 0; j < 4; j++) charges[1 + j] = 0;
6117 for (j = 0; j < ie[0] && !(ie[1 + j] & 0x80); j++);
6118 for (k = 1, j++; j < ie[0] && k <= 4; j++, k++) charges[k] = ie[1 + j];
6119 Info_Number = 0x4000;
6120 Info_Mask = 0x40;
6121 Info_Element = charges;
6122 break;
6123 case 11: /* user user info */
6124 dbug(1, dprintf("uui"));
6125 Info_Number = 0x007E;
6126 Info_Mask = 0x08;
6127 break;
6128 case 12: /* congestion receiver ready */
6129 dbug(1, dprintf("clRDY"));
6130 Info_Number = 0x00B0;
6131 Info_Mask = 0x08;
6132 Info_Element = "";
6133 break;
6134 case 13: /* congestion receiver not ready */
6135 dbug(1, dprintf("clNRDY"));
6136 Info_Number = 0x00BF;
6137 Info_Mask = 0x08;
6138 Info_Element = "";
6139 break;
6140 case 15: /* Keypad Facility */
6141 dbug(1, dprintf("KEY"));
6142 Info_Number = 0x002C;
6143 Info_Mask = 0x20;
6144 break;
6145 case 16: /* Channel Id */
6146 dbug(1, dprintf("CHI"));
6147 Info_Number = 0x0018;
6148 Info_Mask = 0x100;
6149 mixer_set_bchannel_id(plci, Info_Element);
6150 break;
6151 case 17: /* if no 1tr6 cause, send full cause, else esc_cause */
6152 dbug(1, dprintf("q9cau(0x%x)", ie[2]));
6153 if (!cause[2] || cause[2] < 0x80) break; /* eg. layer 1 error */
6154 Info_Number = 0x0008;
6155 Info_Mask = 0x01;
6156 if (cause[2] != ie[2]) Info_Element = cause;
6157 break;
6158 case 19: /* Redirected Number */
6159 dbug(1, dprintf("RDN"));
6160 Info_Number = 0x0074;
6161 Info_Mask = 0x400;
6162 break;
6163 case 22: /* Redirecing Number */
6164 dbug(1, dprintf("RIN"));
6165 Info_Number = 0x0076;
6166 Info_Mask = 0x400;
6167 break;
6168 case 23: /* Notification Indicator */
6169 dbug(1, dprintf("NI"));
6170 Info_Number = (word)NI;
6171 Info_Mask = 0x210;
6172 break;
6173 case 26: /* Call State */
6174 dbug(1, dprintf("CST"));
6175 Info_Number = (word)CST;
6176 Info_Mask = 0x01; /* do with cause i.e. for now */
6177 break;
6178 case MAXPARMSIDS - 2: /* Escape Message Type, must be the last indication */
6179 dbug(1, dprintf("ESC/MT[0x%x]", ie[3]));
6180 Info_Number = 0x8000 | ie[3];
6181 if (iesent) Info_Mask = 0xffff;
6182 else Info_Mask = 0x10;
6183 Info_Element = "";
6184 break;
6185 default:
6186 Info_Number = 0;
6187 Info_Mask = 0;
6188 Info_Element = "";
6189 break;
6190 }
6191 }
6192
6193 if (plci->Sig.Ind == NCR_FACILITY) /* check controller broadcast */
6194 {
6195 for (j = 0; j < max_appl; j++)
6196 {
6197 appl = &application[j];
6198 if (Info_Number
6199 && appl->Id
6200 && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask)
6201 {
6202 dbug(1, dprintf("NCR_Ind"));
6203 iesent = true;
6204 sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element);
6205 }
6206 }
6207 }
6208 else if (!plci->appl)
6209 { /* overlap receiving broadcast */
6210 if (Info_Number == CPN
6211 || Info_Number == KEY
6212 || Info_Number == NI
6213 || Info_Number == DSP
6214 || Info_Number == UUI)
6215 {
6216 for_each_set_bit(j, plci->c_ind_mask_table, max_appl) {
6217 dbug(1, dprintf("Ovl_Ind"));
6218 iesent = true;
6219 sendf(&application[j], _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
6220 }
6221 }
6222 } /* all other signalling states */
6223 else if (Info_Number
6224 && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask)
6225 {
6226 dbug(1, dprintf("Std_Ind"));
6227 iesent = true;
6228 sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
6229 }
6230 }
6231}
6232
6233
6234static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type,
6235 dword info_mask, byte setupParse)
6236{
6237 word i;
6238 word j;
6239 byte *ie;
6240 word Info_Number;
6241 byte *Info_Element;
6242 APPL *appl;
6243 word Info_Mask = 0;
6244 byte iesent = 0;
6245
6246 if (
6247 !plci->appl
6248 && !plci->State
6249 && plci->Sig.Ind != NCR_FACILITY
6250 && !setupParse
6251 )
6252 {
6253 dbug(1, dprintf("NoM-IEParse "));
6254 return 0;
6255 }
6256 dbug(1, dprintf("M-IEParse "));
6257
6258 for (i = 0; i < MAX_MULTI_IE; i++)
6259 {
6260 ie = parms[i];
6261 Info_Number = 0;
6262 Info_Element = ie;
6263 if (ie[0])
6264 {
6265 dbug(1, dprintf("[Ind0x%x]:IE=0x%x", plci->Sig.Ind, ie_type));
6266 Info_Number = (word)ie_type;
6267 Info_Mask = (word)info_mask;
6268 }
6269
6270 if (plci->Sig.Ind == NCR_FACILITY) /* check controller broadcast */
6271 {
6272 for (j = 0; j < max_appl; j++)
6273 {
6274 appl = &application[j];
6275 if (Info_Number
6276 && appl->Id
6277 && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask)
6278 {
6279 iesent = true;
6280 dbug(1, dprintf("Mlt_NCR_Ind"));
6281 sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element);
6282 }
6283 }
6284 }
6285 else if (!plci->appl && Info_Number)
6286 { /* overlap receiving broadcast */
6287 for_each_set_bit(j, plci->c_ind_mask_table, max_appl) {
6288 iesent = true;
6289 dbug(1, dprintf("Mlt_Ovl_Ind"));
6290 sendf(&application[j] , _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
6291 }
6292 } /* all other signalling states */
6293 else if (Info_Number
6294 && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask)
6295 {
6296 iesent = true;
6297 dbug(1, dprintf("Mlt_Std_Ind"));
6298 sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
6299 }
6300 }
6301 return iesent;
6302}
6303
6304static void SendSSExtInd(APPL *appl, PLCI *plci, dword Id, byte **parms)
6305{
6306 word i;
6307 /* Format of multi_ssext_parms[i][]:
6308 0 byte length
6309 1 byte SSEXTIE
6310 2 byte SSEXT_REQ/SSEXT_IND
6311 3 byte length
6312 4 word SSExtCommand
6313 6... Params
6314 */
6315 if (
6316 plci
6317 && plci->State
6318 && plci->Sig.Ind != NCR_FACILITY
6319 )
6320 for (i = 0; i < MAX_MULTI_IE; i++)
6321 {
6322 if (parms[i][0] < 6) continue;
6323 if (parms[i][2] == SSEXT_REQ) continue;
6324
6325 if (appl)
6326 {
6327 parms[i][0] = 0; /* kill it */
6328 sendf(appl, _MANUFACTURER_I,
6329 Id,
6330 0,
6331 "dwS",
6332 _DI_MANU_ID,
6333 _DI_SSEXT_CTRL,
6334 &parms[i][3]);
6335 }
6336 else if (plci->appl)
6337 {
6338 parms[i][0] = 0; /* kill it */
6339 sendf(plci->appl, _MANUFACTURER_I,
6340 Id,
6341 0,
6342 "dwS",
6343 _DI_MANU_ID,
6344 _DI_SSEXT_CTRL,
6345 &parms[i][3]);
6346 }
6347 }
6348};
6349
6350static void nl_ind(PLCI *plci)
6351{
6352 byte ch;
6353 word ncci;
6354 dword Id;
6355 DIVA_CAPI_ADAPTER *a;
6356 word NCCIcode;
6357 APPL *APPLptr;
6358 word count;
6359 word Num;
6360 word i, ncpi_state;
6361 byte len, ncci_state;
6362 word msg;
6363 word info = 0;
6364 word fax_feature_bits;
6365 byte fax_send_edata_ack;
6366 static byte v120_header_buffer[2 + 3];
6367 static word fax_info[] = {
6368 0, /* T30_SUCCESS */
6369 _FAX_NO_CONNECTION, /* T30_ERR_NO_DIS_RECEIVED */
6370 _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_NO_RESPONSE */
6371 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_RESPONSE */
6372 _FAX_PROTOCOL_ERROR, /* T30_ERR_TOO_MANY_REPEATS */
6373 _FAX_PROTOCOL_ERROR, /* T30_ERR_UNEXPECTED_MESSAGE */
6374 _FAX_REMOTE_ABORT, /* T30_ERR_UNEXPECTED_DCN */
6375 _FAX_LOCAL_ABORT, /* T30_ERR_DTC_UNSUPPORTED */
6376 _FAX_TRAINING_ERROR, /* T30_ERR_ALL_RATES_FAILED */
6377 _FAX_TRAINING_ERROR, /* T30_ERR_TOO_MANY_TRAINS */
6378 _FAX_PARAMETER_ERROR, /* T30_ERR_RECEIVE_CORRUPTED */
6379 _FAX_REMOTE_ABORT, /* T30_ERR_UNEXPECTED_DISC */
6380 _FAX_LOCAL_ABORT, /* T30_ERR_APPLICATION_DISC */
6381 _FAX_REMOTE_REJECT, /* T30_ERR_INCOMPATIBLE_DIS */
6382 _FAX_LOCAL_ABORT, /* T30_ERR_INCOMPATIBLE_DCS */
6383 _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_NO_COMMAND */
6384 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_COMMAND */
6385 _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG */
6386 _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG */
6387 _FAX_NO_CONNECTION, /* T30_ERR_NOT_IDENTIFIED */
6388 _FAX_PROTOCOL_ERROR, /* T30_ERR_SUPERVISORY_TIMEOUT */
6389 _FAX_PARAMETER_ERROR, /* T30_ERR_TOO_LONG_SCAN_LINE */
6390 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS */
6391 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR */
6392 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_FTT */
6393 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_EOM */
6394 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_MPS */
6395 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCN_AFTER_MCF */
6396 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCN_AFTER_RTN */
6397 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_CFR */
6398 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_EOP */
6399 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_EOM */
6400 _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_MPS */
6401 0x331d, /* T30_ERR_SUB_SEP_UNSUPPORTED */
6402 0x331e, /* T30_ERR_PWD_UNSUPPORTED */
6403 0x331f, /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED */
6404 _FAX_PROTOCOL_ERROR, /* T30_ERR_INVALID_COMMAND_FRAME */
6405 _FAX_PARAMETER_ERROR, /* T30_ERR_UNSUPPORTED_PAGE_CODING */
6406 _FAX_PARAMETER_ERROR, /* T30_ERR_INVALID_PAGE_CODING */
6407 _FAX_REMOTE_REJECT, /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG */
6408 _FAX_LOCAL_ABORT, /* T30_ERR_TIMEOUT_FROM_APPLICATION */
6409 _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */
6410 _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_TRAINING_TIMEOUT */
6411 _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_UNEXPECTED_V21 */
6412 _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_PRIMARY_CTS_ON */
6413 _FAX_LOCAL_ABORT, /* T30_ERR_V34FAX_TURNAROUND_POLLING */
6414 _FAX_LOCAL_ABORT /* T30_ERR_V34FAX_V8_INCOMPATIBILITY */
6415 };
6416
6417 byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1];
6418
6419
6420 static word rtp_info[] = {
6421 GOOD, /* RTP_SUCCESS */
6422 0x3600 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE */
6423 };
6424
6425 static dword udata_forwarding_table[0x100 / sizeof(dword)] =
6426 {
6427 0x0020301e, 0x00000000, 0x00000000, 0x00000000,
6428 0x00000000, 0x00000000, 0x00000000, 0x00000000
6429 };
6430
6431 ch = plci->NL.IndCh;
6432 a = plci->adapter;
6433 ncci = a->ch_ncci[ch];
6434 Id = (((dword)(ncci ? ncci : ch)) << 16) | (((word) plci->Id) << 8) | a->Id;
6435 if (plci->tel) Id |= EXT_CONTROLLER;
6436 APPLptr = plci->appl;
6437 dbug(1, dprintf("NL_IND-Id(NL:0x%x)=0x%08lx,plci=%x,tel=%x,state=0x%x,ch=0x%x,chs=%d,Ind=%x",
6438 plci->NL.Id, Id, plci->Id, plci->tel, plci->State, ch, plci->channels, plci->NL.Ind & 0x0f));
6439
6440 /* in the case if no connect_active_Ind was sent to the appl we wait for */
6441
6442 if (plci->nl_remove_id)
6443 {
6444 plci->NL.RNR = 2; /* discard */
6445 dbug(1, dprintf("NL discard while remove pending"));
6446 return;
6447 }
6448 if ((plci->NL.Ind & 0x0f) == N_CONNECT)
6449 {
6450 if (plci->State == INC_DIS_PENDING
6451 || plci->State == OUTG_DIS_PENDING
6452 || plci->State == IDLE)
6453 {
6454 plci->NL.RNR = 2; /* discard */
6455 dbug(1, dprintf("discard n_connect"));
6456 return;
6457 }
6458 if (plci->State < INC_ACT_PENDING)
6459 {
6460 plci->NL.RNR = 1; /* flow control */
6461 channel_x_off(plci, ch, N_XON_CONNECT_IND);
6462 return;
6463 }
6464 }
6465
6466 if (!APPLptr) /* no application or invalid data */
6467 { /* while reloading the DSP */
6468 dbug(1, dprintf("discard1"));
6469 plci->NL.RNR = 2;
6470 return;
6471 }
6472
6473 if (((plci->NL.Ind & 0x0f) == N_UDATA)
6474 && (((plci->B2_prot != B2_SDLC) && ((plci->B1_resource == 17) || (plci->B1_resource == 18)))
6475 || (plci->B2_prot == 7)
6476 || (plci->B3_prot == 7)))
6477 {
6478 plci->ncpi_buffer[0] = 0;
6479
6480 ncpi_state = plci->ncpi_state;
6481 if (plci->NL.complete == 1)
6482 {
6483 byte *data = &plci->NL.RBuffer->P[0];
6484
6485 if ((plci->NL.RBuffer->length >= 12)
6486 && ((*data == DSP_UDATA_INDICATION_DCD_ON)
6487 || (*data == DSP_UDATA_INDICATION_CTS_ON)))
6488 {
6489 word conn_opt, ncpi_opt = 0x00;
6490/* HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
6491
6492 if (*data == DSP_UDATA_INDICATION_DCD_ON)
6493 plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED;
6494 if (*data == DSP_UDATA_INDICATION_CTS_ON)
6495 plci->ncpi_state |= NCPI_MDM_CTS_ON_RECEIVED;
6496
6497 data++; /* indication code */
6498 data += 2; /* timestamp */
6499 if ((*data == DSP_CONNECTED_NORM_V18) || (*data == DSP_CONNECTED_NORM_VOWN))
6500 ncpi_state &= ~(NCPI_MDM_DCD_ON_RECEIVED | NCPI_MDM_CTS_ON_RECEIVED);
6501 data++; /* connected norm */
6502 conn_opt = GET_WORD(data);
6503 data += 2; /* connected options */
6504
6505 PUT_WORD(&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF));
6506
6507 if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42)
6508 {
6509 ncpi_opt |= MDM_NCPI_ECM_V42;
6510 }
6511 else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP)
6512 {
6513 ncpi_opt |= MDM_NCPI_ECM_MNP;
6514 }
6515 else
6516 {
6517 ncpi_opt |= MDM_NCPI_TRANSPARENT;
6518 }
6519 if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION)
6520 {
6521 ncpi_opt |= MDM_NCPI_COMPRESSED;
6522 }
6523 PUT_WORD(&(plci->ncpi_buffer[3]), ncpi_opt);
6524 plci->ncpi_buffer[0] = 4;
6525
6526 plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
6527 }
6528 }
6529 if (plci->B3_prot == 7)
6530 {
6531 if (((a->ncci_state[ncci] == INC_ACT_PENDING) || (a->ncci_state[ncci] == OUTG_CON_PENDING))
6532 && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
6533 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
6534 {
6535 a->ncci_state[ncci] = INC_ACT_PENDING;
6536 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
6537 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
6538 }
6539 }
6540
6541 if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
6542 & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
6543 || !(ncpi_state & NCPI_MDM_DCD_ON_RECEIVED)
6544 || !(ncpi_state & NCPI_MDM_CTS_ON_RECEIVED))
6545
6546 {
6547 plci->NL.RNR = 2;
6548 return;
6549 }
6550 }
6551
6552 if (plci->NL.complete == 2)
6553 {
6554 if (((plci->NL.Ind & 0x0f) == N_UDATA)
6555 && !(udata_forwarding_table[plci->RData[0].P[0] >> 5] & (1L << (plci->RData[0].P[0] & 0x1f))))
6556 {
6557 switch (plci->RData[0].P[0])
6558 {
6559
6560 case DTMF_UDATA_INDICATION_FAX_CALLING_TONE:
6561 if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
6562 sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01X");
6563 break;
6564 case DTMF_UDATA_INDICATION_ANSWER_TONE:
6565 if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
6566 sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01Y");
6567 break;
6568 case DTMF_UDATA_INDICATION_DIGITS_RECEIVED:
6569 dtmf_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
6570 break;
6571 case DTMF_UDATA_INDICATION_DIGITS_SENT:
6572 dtmf_confirmation(Id, plci);
6573 break;
6574
6575
6576 case UDATA_INDICATION_MIXER_TAP_DATA:
6577 capidtmf_recv_process_block(&(plci->capidtmf_state), plci->RData[0].P + 1, (word)(plci->RData[0].PLength - 1));
6578 i = capidtmf_indication(&(plci->capidtmf_state), dtmf_code_buffer + 1);
6579 if (i != 0)
6580 {
6581 dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED;
6582 dtmf_indication(Id, plci, dtmf_code_buffer, (word)(i + 1));
6583 }
6584 break;
6585
6586
6587 case UDATA_INDICATION_MIXER_COEFS_SET:
6588 mixer_indication_coefs_set(Id, plci);
6589 break;
6590 case UDATA_INDICATION_XCONNECT_FROM:
6591 mixer_indication_xconnect_from(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
6592 break;
6593 case UDATA_INDICATION_XCONNECT_TO:
6594 mixer_indication_xconnect_to(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
6595 break;
6596
6597
6598 case LEC_UDATA_INDICATION_DISABLE_DETECT:
6599 ec_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
6600 break;
6601
6602
6603
6604 default:
6605 break;
6606 }
6607 }
6608 else
6609 {
6610 if ((plci->RData[0].PLength != 0)
6611 && ((plci->B2_prot == B2_V120_ASYNC)
6612 || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
6613 || (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
6614 {
6615
6616 sendf(plci->appl, _DATA_B3_I, Id, 0,
6617 "dwww",
6618 plci->RData[1].P,
6619 (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength,
6620 plci->RNum,
6621 plci->RFlags);
6622
6623 }
6624 else
6625 {
6626
6627 sendf(plci->appl, _DATA_B3_I, Id, 0,
6628 "dwww",
6629 plci->RData[0].P,
6630 plci->RData[0].PLength,
6631 plci->RNum,
6632 plci->RFlags);
6633
6634 }
6635 }
6636 return;
6637 }
6638
6639 fax_feature_bits = 0;
6640 if ((plci->NL.Ind & 0x0f) == N_CONNECT ||
6641 (plci->NL.Ind & 0x0f) == N_CONNECT_ACK ||
6642 (plci->NL.Ind & 0x0f) == N_DISC ||
6643 (plci->NL.Ind & 0x0f) == N_EDATA ||
6644 (plci->NL.Ind & 0x0f) == N_DISC_ACK)
6645 {
6646 info = 0;
6647 plci->ncpi_buffer[0] = 0;
6648 switch (plci->B3_prot) {
6649 case 0: /*XPARENT*/
6650 case 1: /*T.90 NL*/
6651 break; /* no network control protocol info - jfr */
6652 case 2: /*ISO8202*/
6653 case 3: /*X25 DCE*/
6654 for (i = 0; i < plci->NL.RLength; i++) plci->ncpi_buffer[4 + i] = plci->NL.RBuffer->P[i];
6655 plci->ncpi_buffer[0] = (byte)(i + 3);
6656 plci->ncpi_buffer[1] = (byte)(plci->NL.Ind & N_D_BIT ? 1 : 0);
6657 plci->ncpi_buffer[2] = 0;
6658 plci->ncpi_buffer[3] = 0;
6659 break;
6660 case 4: /*T.30 - FAX*/
6661 case 5: /*T.30 - FAX*/
6662 if (plci->NL.RLength >= sizeof(T30_INFO))
6663 {
6664 dbug(1, dprintf("FaxStatus %04x", ((T30_INFO *)plci->NL.RBuffer->P)->code));
6665 len = 9;
6666 PUT_WORD(&(plci->ncpi_buffer[1]), ((T30_INFO *)plci->NL.RBuffer->P)->rate_div_2400 * 2400);
6667 fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low);
6668 i = (((T30_INFO *)plci->NL.RBuffer->P)->resolution & T30_RESOLUTION_R8_0770_OR_200) ? 0x0001 : 0x0000;
6669 if (plci->B3_prot == 5)
6670 {
6671 if (!(fax_feature_bits & T30_FEATURE_BIT_ECM))
6672 i |= 0x8000; /* This is not an ECM connection */
6673 if (fax_feature_bits & T30_FEATURE_BIT_T6_CODING)
6674 i |= 0x4000; /* This is a connection with MMR compression */
6675 if (fax_feature_bits & T30_FEATURE_BIT_2D_CODING)
6676 i |= 0x2000; /* This is a connection with MR compression */
6677 if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
6678 i |= 0x0004; /* More documents */
6679 if (fax_feature_bits & T30_FEATURE_BIT_POLLING)
6680 i |= 0x0002; /* Fax-polling indication */
6681 }
6682 dbug(1, dprintf("FAX Options %04x %04x", fax_feature_bits, i));
6683 PUT_WORD(&(plci->ncpi_buffer[3]), i);
6684 PUT_WORD(&(plci->ncpi_buffer[5]), ((T30_INFO *)plci->NL.RBuffer->P)->data_format);
6685 plci->ncpi_buffer[7] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_low;
6686 plci->ncpi_buffer[8] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_high;
6687 plci->ncpi_buffer[len] = 0;
6688 if (((T30_INFO *)plci->NL.RBuffer->P)->station_id_len)
6689 {
6690 plci->ncpi_buffer[len] = 20;
6691 for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
6692 plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i];
6693 }
6694 if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
6695 {
6696 if (((T30_INFO *)plci->NL.RBuffer->P)->code < ARRAY_SIZE(fax_info))
6697 info = fax_info[((T30_INFO *)plci->NL.RBuffer->P)->code];
6698 else
6699 info = _FAX_PROTOCOL_ERROR;
6700 }
6701
6702 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
6703 & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
6704 {
6705 i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
6706 while (i < plci->NL.RBuffer->length)
6707 plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
6708 }
6709
6710 plci->ncpi_buffer[0] = len;
6711 fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low);
6712 PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low, fax_feature_bits);
6713
6714 plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND;
6715 if (((plci->NL.Ind & 0x0f) == N_CONNECT_ACK)
6716 || (((plci->NL.Ind & 0x0f) == N_CONNECT)
6717 && (fax_feature_bits & T30_FEATURE_BIT_POLLING))
6718 || (((plci->NL.Ind & 0x0f) == N_EDATA)
6719 && ((((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_TRAIN_OK)
6720 || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
6721 || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DTC))))
6722 {
6723 plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT;
6724 }
6725 if (((plci->NL.Ind & 0x0f) == N_DISC)
6726 || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)
6727 || (((plci->NL.Ind & 0x0f) == N_EDATA)
6728 && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_EOP_CAPI)))
6729 {
6730 plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
6731 }
6732 }
6733 break;
6734
6735 case B3_RTP:
6736 if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
6737 {
6738 if (plci->NL.RLength != 0)
6739 {
6740 info = rtp_info[plci->NL.RBuffer->P[0]];
6741 plci->ncpi_buffer[0] = plci->NL.RLength - 1;
6742 for (i = 1; i < plci->NL.RLength; i++)
6743 plci->ncpi_buffer[i] = plci->NL.RBuffer->P[i];
6744 }
6745 }
6746 break;
6747
6748 }
6749 plci->NL.RNR = 2;
6750 }
6751 switch (plci->NL.Ind & 0x0f) {
6752 case N_EDATA:
6753 if ((plci->B3_prot == 4) || (plci->B3_prot == 5))
6754 {
6755 dbug(1, dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci, a->ncci_state[ncci],
6756 ((T30_INFO *)plci->NL.RBuffer->P)->code));
6757 fax_send_edata_ack = (((T30_INFO *)(plci->fax_connect_info_buffer))->operating_mode == T30_OPERATING_MODE_CAPI_NEG);
6758
6759 if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
6760 && (plci->nsf_control_bits & (T30_NSF_CONTROL_BIT_NEGOTIATE_IND | T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
6761 && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
6762 && (a->ncci_state[ncci] == OUTG_CON_PENDING)
6763 && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
6764 && !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
6765 {
6766 ((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code;
6767 sendf(plci->appl, _MANUFACTURER_I, Id, 0, "dwbS", _DI_MANU_ID, _DI_NEGOTIATE_B3,
6768 (byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer);
6769 plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT;
6770 if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)
6771 fax_send_edata_ack = false;
6772 }
6773
6774 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
6775 {
6776 switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
6777 {
6778 case EDATA_T30_DIS:
6779 if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
6780 && !(GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) & T30_CONTROL_BIT_REQUEST_POLLING)
6781 && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
6782 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
6783 {
6784 a->ncci_state[ncci] = INC_ACT_PENDING;
6785 if (plci->B3_prot == 4)
6786 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
6787 else
6788 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
6789 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
6790 }
6791 break;
6792
6793 case EDATA_T30_TRAIN_OK:
6794 if ((a->ncci_state[ncci] == INC_ACT_PENDING)
6795 && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
6796 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
6797 {
6798 if (plci->B3_prot == 4)
6799 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
6800 else
6801 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
6802 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
6803 }
6804 break;
6805
6806 case EDATA_T30_EOP_CAPI:
6807 if (a->ncci_state[ncci] == CONNECTED)
6808 {
6809 sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", GOOD, plci->ncpi_buffer);
6810 a->ncci_state[ncci] = INC_DIS_PENDING;
6811 plci->ncpi_state = 0;
6812 fax_send_edata_ack = false;
6813 }
6814 break;
6815 }
6816 }
6817 else
6818 {
6819 switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
6820 {
6821 case EDATA_T30_TRAIN_OK:
6822 if ((a->ncci_state[ncci] == INC_ACT_PENDING)
6823 && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
6824 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
6825 {
6826 if (plci->B3_prot == 4)
6827 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
6828 else
6829 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
6830 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
6831 }
6832 break;
6833 }
6834 }
6835 if (fax_send_edata_ack)
6836 {
6837 ((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code;
6838 plci->fax_edata_ack_length = 1;
6839 start_internal_command(Id, plci, fax_edata_ack_command);
6840 }
6841 }
6842 else
6843 {
6844 dbug(1, dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci]));
6845 }
6846 break;
6847 case N_CONNECT:
6848 if (!a->ch_ncci[ch])
6849 {
6850 ncci = get_ncci(plci, ch, 0);
6851 Id = (Id & 0xffff) | (((dword) ncci) << 16);
6852 }
6853 dbug(1, dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d",
6854 ch, a->ncci_state[ncci], a->ncci_plci[ncci], plci->Id, plci->State));
6855
6856 msg = _CONNECT_B3_I;
6857 if (a->ncci_state[ncci] == IDLE)
6858 plci->channels++;
6859 else if (plci->B3_prot == 1)
6860 msg = _CONNECT_B3_T90_ACTIVE_I;
6861
6862 a->ncci_state[ncci] = INC_CON_PENDING;
6863 if (plci->B3_prot == 4)
6864 sendf(plci->appl, msg, Id, 0, "s", "");
6865 else
6866 sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
6867 break;
6868 case N_CONNECT_ACK:
6869 dbug(1, dprintf("N_connect_Ack"));
6870 if (plci->internal_command_queue[0]
6871 && ((plci->adjust_b_state == ADJUST_B_CONNECT_2)
6872 || (plci->adjust_b_state == ADJUST_B_CONNECT_3)
6873 || (plci->adjust_b_state == ADJUST_B_CONNECT_4)))
6874 {
6875 (*(plci->internal_command_queue[0]))(Id, plci, 0);
6876 if (!plci->internal_command)
6877 next_internal_command(Id, plci);
6878 break;
6879 }
6880 msg = _CONNECT_B3_ACTIVE_I;
6881 if (plci->B3_prot == 1)
6882 {
6883 if (a->ncci_state[ncci] != OUTG_CON_PENDING)
6884 msg = _CONNECT_B3_T90_ACTIVE_I;
6885 a->ncci_state[ncci] = INC_ACT_PENDING;
6886 sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
6887 }
6888 else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
6889 {
6890 if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
6891 && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
6892 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
6893 {
6894 a->ncci_state[ncci] = INC_ACT_PENDING;
6895 if (plci->B3_prot == 4)
6896 sendf(plci->appl, msg, Id, 0, "s", "");
6897 else
6898 sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
6899 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
6900 }
6901 }
6902 else
6903 {
6904 a->ncci_state[ncci] = INC_ACT_PENDING;
6905 sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
6906 }
6907 if (plci->adjust_b_restore)
6908 {
6909 plci->adjust_b_restore = false;
6910 start_internal_command(Id, plci, adjust_b_restore);
6911 }
6912 break;
6913 case N_DISC:
6914 case N_DISC_ACK:
6915 if (plci->internal_command_queue[0]
6916 && ((plci->internal_command == FAX_DISCONNECT_COMMAND_1)
6917 || (plci->internal_command == FAX_DISCONNECT_COMMAND_2)
6918 || (plci->internal_command == FAX_DISCONNECT_COMMAND_3)))
6919 {
6920 (*(plci->internal_command_queue[0]))(Id, plci, 0);
6921 if (!plci->internal_command)
6922 next_internal_command(Id, plci);
6923 }
6924 ncci_state = a->ncci_state[ncci];
6925 ncci_remove(plci, ncci, false);
6926
6927 /* with N_DISC or N_DISC_ACK the IDI frees the respective */
6928 /* channel, so we cannot store the state in ncci_state! The */
6929 /* information which channel we received a N_DISC is thus */
6930 /* stored in the inc_dis_ncci_table buffer. */
6931 for (i = 0; plci->inc_dis_ncci_table[i]; i++);
6932 plci->inc_dis_ncci_table[i] = (byte) ncci;
6933
6934 /* need a connect_b3_ind before a disconnect_b3_ind with FAX */
6935 if (!plci->channels
6936 && (plci->B1_resource == 16)
6937 && (plci->State <= CONNECTED))
6938 {
6939 len = 9;
6940 i = ((T30_INFO *)plci->fax_connect_info_buffer)->rate_div_2400 * 2400;
6941 PUT_WORD(&plci->ncpi_buffer[1], i);
6942 PUT_WORD(&plci->ncpi_buffer[3], 0);
6943 i = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format;
6944 PUT_WORD(&plci->ncpi_buffer[5], i);
6945 PUT_WORD(&plci->ncpi_buffer[7], 0);
6946 plci->ncpi_buffer[len] = 0;
6947 plci->ncpi_buffer[0] = len;
6948 if (plci->B3_prot == 4)
6949 sendf(plci->appl, _CONNECT_B3_I, Id, 0, "s", "");
6950 else
6951 {
6952
6953 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
6954 & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
6955 {
6956 plci->ncpi_buffer[++len] = 0;
6957 plci->ncpi_buffer[++len] = 0;
6958 plci->ncpi_buffer[++len] = 0;
6959 plci->ncpi_buffer[0] = len;
6960 }
6961
6962 sendf(plci->appl, _CONNECT_B3_I, Id, 0, "S", plci->ncpi_buffer);
6963 }
6964 sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer);
6965 plci->ncpi_state = 0;
6966 sig_req(plci, HANGUP, 0);
6967 send_req(plci);
6968 plci->State = OUTG_DIS_PENDING;
6969 /* disc here */
6970 }
6971 else if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
6972 && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
6973 && ((ncci_state == INC_DIS_PENDING) || (ncci_state == IDLE)))
6974 {
6975 if (ncci_state == IDLE)
6976 {
6977 if (plci->channels)
6978 plci->channels--;
6979 if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) {
6980 if (plci->State == SUSPENDING) {
6981 sendf(plci->appl,
6982 _FACILITY_I,
6983 Id & 0xffffL,
6984 0,
6985 "ws", (word)3, "\x03\x04\x00\x00");
6986 sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
6987 }
6988 plci_remove(plci);
6989 plci->State = IDLE;
6990 }
6991 }
6992 }
6993 else if (plci->channels)
6994 {
6995 sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer);
6996 plci->ncpi_state = 0;
6997 if ((ncci_state == OUTG_REJ_PENDING)
6998 && ((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)))
6999 {
7000 sig_req(plci, HANGUP, 0);
7001 send_req(plci);
7002 plci->State = OUTG_DIS_PENDING;
7003 }
7004 }
7005 break;
7006 case N_RESET:
7007 a->ncci_state[ncci] = INC_RES_PENDING;
7008 sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer);
7009 break;
7010 case N_RESET_ACK:
7011 a->ncci_state[ncci] = CONNECTED;
7012 sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer);
7013 break;
7014
7015 case N_UDATA:
7016 if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
7017 {
7018 plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3);
7019 plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE;
7020 plci->NL.R = plci->RData;
7021 plci->NL.RNum = 1;
7022 return;
7023 }
7024 /* fall through */
7025 case N_BDATA:
7026 case N_DATA:
7027 if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */
7028 || (a->ncci_state[ncci] == IDLE)
7029 || (a->ncci_state[ncci] == INC_DIS_PENDING))
7030 {
7031 plci->NL.RNR = 2;
7032 break;
7033 }
7034 if ((a->ncci_state[ncci] != CONNECTED)
7035 && (a->ncci_state[ncci] != OUTG_DIS_PENDING)
7036 && (a->ncci_state[ncci] != OUTG_REJ_PENDING))
7037 {
7038 dbug(1, dprintf("flow control"));
7039 plci->NL.RNR = 1; /* flow control */
7040 channel_x_off(plci, ch, 0);
7041 break;
7042 }
7043
7044 NCCIcode = ncci | (((word)a->Id) << 8);
7045
7046 /* count all buffers within the Application pool */
7047 /* belonging to the same NCCI. If this is below the */
7048 /* number of buffers available per NCCI we accept */
7049 /* this packet, otherwise we reject it */
7050 count = 0;
7051 Num = 0xffff;
7052 for (i = 0; i < APPLptr->MaxBuffer; i++) {
7053 if (NCCIcode == APPLptr->DataNCCI[i]) count++;
7054 if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i;
7055 }
7056
7057 if (count >= APPLptr->MaxNCCIData || Num == 0xffff)
7058 {
7059 dbug(3, dprintf("Flow-Control"));
7060 plci->NL.RNR = 1;
7061 if (++(APPLptr->NCCIDataFlowCtrlTimer) >=
7062 (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000))
7063 {
7064 plci->NL.RNR = 2;
7065 dbug(3, dprintf("DiscardData"));
7066 } else {
7067 channel_x_off(plci, ch, 0);
7068 }
7069 break;
7070 }
7071 else
7072 {
7073 APPLptr->NCCIDataFlowCtrlTimer = 0;
7074 }
7075
7076 plci->RData[0].P = ReceiveBufferGet(APPLptr, Num);
7077 if (!plci->RData[0].P) {
7078 plci->NL.RNR = 1;
7079 channel_x_off(plci, ch, 0);
7080 break;
7081 }
7082
7083 APPLptr->DataNCCI[Num] = NCCIcode;
7084 APPLptr->DataFlags[Num] = (plci->Id << 8) | (plci->NL.Ind >> 4);
7085 dbug(3, dprintf("Buffer(%d), Max = %d", Num, APPLptr->MaxBuffer));
7086
7087 plci->RNum = Num;
7088 plci->RFlags = plci->NL.Ind >> 4;
7089 plci->RData[0].PLength = APPLptr->MaxDataLength;
7090 plci->NL.R = plci->RData;
7091 if ((plci->NL.RLength != 0)
7092 && ((plci->B2_prot == B2_V120_ASYNC)
7093 || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
7094 || (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
7095 {
7096 plci->RData[1].P = plci->RData[0].P;
7097 plci->RData[1].PLength = plci->RData[0].PLength;
7098 plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3);
7099 if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1))
7100 plci->RData[0].PLength = 1;
7101 else
7102 plci->RData[0].PLength = 2;
7103 if (plci->NL.RBuffer->P[0] & V120_HEADER_BREAK_BIT)
7104 plci->RFlags |= 0x0010;
7105 if (plci->NL.RBuffer->P[0] & (V120_HEADER_C1_BIT | V120_HEADER_C2_BIT))
7106 plci->RFlags |= 0x8000;
7107 plci->NL.RNum = 2;
7108 }
7109 else
7110 {
7111 if ((plci->NL.Ind & 0x0f) == N_UDATA)
7112 plci->RFlags |= 0x0010;
7113
7114 else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA))
7115 plci->RFlags |= 0x0001;
7116
7117 plci->NL.RNum = 1;
7118 }
7119 break;
7120 case N_DATA_ACK:
7121 data_ack(plci, ch);
7122 break;
7123 default:
7124 plci->NL.RNR = 2;
7125 break;
7126 }
7127}
7128
7129/*------------------------------------------------------------------*/
7130/* find a free PLCI */
7131/*------------------------------------------------------------------*/
7132
7133static word get_plci(DIVA_CAPI_ADAPTER *a)
7134{
7135 word i, j;
7136 PLCI *plci;
7137
7138 for (i = 0; i < a->max_plci && a->plci[i].Id; i++);
7139 if (i == a->max_plci) {
7140 dbug(1, dprintf("get_plci: out of PLCIs"));
7141 return 0;
7142 }
7143 plci = &a->plci[i];
7144 plci->Id = (byte)(i + 1);
7145
7146 plci->Sig.Id = 0;
7147 plci->NL.Id = 0;
7148 plci->sig_req = 0;
7149 plci->nl_req = 0;
7150
7151 plci->appl = NULL;
7152 plci->relatedPTYPLCI = NULL;
7153 plci->State = IDLE;
7154 plci->SuppState = IDLE;
7155 plci->channels = 0;
7156 plci->tel = 0;
7157 plci->B1_resource = 0;
7158 plci->B2_prot = 0;
7159 plci->B3_prot = 0;
7160
7161 plci->command = 0;
7162 plci->m_command = 0;
7163 init_internal_command_queue(plci);
7164 plci->number = 0;
7165 plci->req_in_start = 0;
7166 plci->req_in = 0;
7167 plci->req_out = 0;
7168 plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
7169 plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
7170 plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
7171
7172 plci->data_sent = false;
7173 plci->send_disc = 0;
7174 plci->sig_global_req = 0;
7175 plci->sig_remove_id = 0;
7176 plci->nl_global_req = 0;
7177 plci->nl_remove_id = 0;
7178 plci->adv_nl = 0;
7179 plci->manufacturer = false;
7180 plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
7181 plci->spoofed_msg = 0;
7182 plci->ptyState = 0;
7183 plci->cr_enquiry = false;
7184 plci->hangup_flow_ctrl_timer = 0;
7185
7186 plci->ncci_ring_list = 0;
7187 for (j = 0; j < MAX_CHANNELS_PER_PLCI; j++) plci->inc_dis_ncci_table[j] = 0;
7188 bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
7189 bitmap_fill(plci->group_optimization_mask_table, MAX_APPL);
7190 plci->fax_connect_info_length = 0;
7191 plci->nsf_control_bits = 0;
7192 plci->ncpi_state = 0x00;
7193 plci->ncpi_buffer[0] = 0;
7194
7195 plci->requested_options_conn = 0;
7196 plci->requested_options = 0;
7197 plci->notifiedcall = 0;
7198 plci->vswitchstate = 0;
7199 plci->vsprot = 0;
7200 plci->vsprotdialect = 0;
7201 init_b1_config(plci);
7202 dbug(1, dprintf("get_plci(%x)", plci->Id));
7203 return i + 1;
7204}
7205
7206/*------------------------------------------------------------------*/
7207/* put a parameter in the parameter buffer */
7208/*------------------------------------------------------------------*/
7209
7210static void add_p(PLCI *plci, byte code, byte *p)
7211{
7212 word p_length;
7213
7214 p_length = 0;
7215 if (p) p_length = p[0];
7216 add_ie(plci, code, p, p_length);
7217}
7218
7219/*------------------------------------------------------------------*/
7220/* put a structure in the parameter buffer */
7221/*------------------------------------------------------------------*/
7222static void add_s(PLCI *plci, byte code, API_PARSE *p)
7223{
7224 if (p) add_ie(plci, code, p->info, (word)p->length);
7225}
7226
7227/*------------------------------------------------------------------*/
7228/* put multiple structures in the parameter buffer */
7229/*------------------------------------------------------------------*/
7230static void add_ss(PLCI *plci, byte code, API_PARSE *p)
7231{
7232 byte i;
7233
7234 if (p) {
7235 dbug(1, dprintf("add_ss(%x,len=%d)", code, p->length));
7236 for (i = 2; i < (byte)p->length; i += p->info[i] + 2) {
7237 dbug(1, dprintf("add_ss_ie(%x,len=%d)", p->info[i - 1], p->info[i]));
7238 add_ie(plci, p->info[i - 1], (byte *)&(p->info[i]), (word)p->info[i]);
7239 }
7240 }
7241}
7242
7243/*------------------------------------------------------------------*/
7244/* return the channel number sent by the application in a esc_chi */
7245/*------------------------------------------------------------------*/
7246static byte getChannel(API_PARSE *p)
7247{
7248 byte i;
7249
7250 if (p) {
7251 for (i = 2; i < (byte)p->length; i += p->info[i] + 2) {
7252 if (p->info[i] == 2) {
7253 if (p->info[i - 1] == ESC && p->info[i + 1] == CHI) return (p->info[i + 2]);
7254 }
7255 }
7256 }
7257 return 0;
7258}
7259
7260
7261/*------------------------------------------------------------------*/
7262/* put an information element in the parameter buffer */
7263/*------------------------------------------------------------------*/
7264
7265static void add_ie(PLCI *plci, byte code, byte *p, word p_length)
7266{
7267 word i;
7268
7269 if (!(code & 0x80) && !p_length) return;
7270
7271 if (plci->req_in == plci->req_in_start) {
7272 plci->req_in += 2;
7273 }
7274 else {
7275 plci->req_in--;
7276 }
7277 plci->RBuffer[plci->req_in++] = code;
7278
7279 if (p) {
7280 plci->RBuffer[plci->req_in++] = (byte)p_length;
7281 for (i = 0; i < p_length; i++) plci->RBuffer[plci->req_in++] = p[1 + i];
7282 }
7283
7284 plci->RBuffer[plci->req_in++] = 0;
7285}
7286
7287/*------------------------------------------------------------------*/
7288/* put a unstructured data into the buffer */
7289/*------------------------------------------------------------------*/
7290
7291static void add_d(PLCI *plci, word length, byte *p)
7292{
7293 word i;
7294
7295 if (plci->req_in == plci->req_in_start) {
7296 plci->req_in += 2;
7297 }
7298 else {
7299 plci->req_in--;
7300 }
7301 for (i = 0; i < length; i++) plci->RBuffer[plci->req_in++] = p[i];
7302}
7303
7304/*------------------------------------------------------------------*/
7305/* put parameters from the Additional Info parameter in the */
7306/* parameter buffer */
7307/*------------------------------------------------------------------*/
7308
7309static void add_ai(PLCI *plci, API_PARSE *ai)
7310{
7311 word i;
7312 API_PARSE ai_parms[5];
7313
7314 for (i = 0; i < 5; i++) ai_parms[i].length = 0;
7315
7316 if (!ai->length)
7317 return;
7318 if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
7319 return;
7320
7321 add_s(plci, KEY, &ai_parms[1]);
7322 add_s(plci, UUI, &ai_parms[2]);
7323 add_ss(plci, FTY, &ai_parms[3]);
7324}
7325
7326/*------------------------------------------------------------------*/
7327/* put parameter for b1 protocol in the parameter buffer */
7328/*------------------------------------------------------------------*/
7329
7330static word add_b1(PLCI *plci, API_PARSE *bp, word b_channel_info,
7331 word b1_facilities)
7332{
7333 API_PARSE bp_parms[8];
7334 API_PARSE mdm_cfg[9];
7335 API_PARSE global_config[2];
7336 byte cai[256];
7337 byte resource[] = {5, 9, 13, 12, 16, 39, 9, 17, 17, 18};
7338 byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08";
7339 word i;
7340
7341 API_PARSE mdm_cfg_v18[4];
7342 word j, n, w;
7343 dword d;
7344
7345
7346 for (i = 0; i < 8; i++) bp_parms[i].length = 0;
7347 for (i = 0; i < 2; i++) global_config[i].length = 0;
7348
7349 dbug(1, dprintf("add_b1"));
7350 api_save_msg(bp, "s", &plci->B_protocol);
7351
7352 if (b_channel_info == 2) {
7353 plci->B1_resource = 0;
7354 adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
7355 add_p(plci, CAI, "\x01\x00");
7356 dbug(1, dprintf("Cai=1,0 (no resource)"));
7357 return 0;
7358 }
7359
7360 if (plci->tel == CODEC_PERMANENT) return 0;
7361 else if (plci->tel == CODEC) {
7362 plci->B1_resource = 1;
7363 adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
7364 add_p(plci, CAI, "\x01\x01");
7365 dbug(1, dprintf("Cai=1,1 (Codec)"));
7366 return 0;
7367 }
7368 else if (plci->tel == ADV_VOICE) {
7369 plci->B1_resource = add_b1_facilities(plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE));
7370 adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE));
7371 voice_cai[1] = plci->B1_resource;
7372 PUT_WORD(&voice_cai[5], plci->appl->MaxDataLength);
7373 add_p(plci, CAI, voice_cai);
7374 dbug(1, dprintf("Cai=1,0x%x (AdvVoice)", voice_cai[1]));
7375 return 0;
7376 }
7377 plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER);
7378 if (plci->call_dir & CALL_DIR_OUT)
7379 plci->call_dir |= CALL_DIR_ORIGINATE;
7380 else if (plci->call_dir & CALL_DIR_IN)
7381 plci->call_dir |= CALL_DIR_ANSWER;
7382
7383 if (!bp->length) {
7384 plci->B1_resource = 0x5;
7385 adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
7386 add_p(plci, CAI, "\x01\x05");
7387 return 0;
7388 }
7389
7390 dbug(1, dprintf("b_prot_len=%d", (word)bp->length));
7391 if (bp->length > 256) return _WRONG_MESSAGE_FORMAT;
7392 if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
7393 {
7394 bp_parms[6].length = 0;
7395 if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
7396 {
7397 dbug(1, dprintf("b-form.!"));
7398 return _WRONG_MESSAGE_FORMAT;
7399 }
7400 }
7401 else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
7402 {
7403 dbug(1, dprintf("b-form.!"));
7404 return _WRONG_MESSAGE_FORMAT;
7405 }
7406
7407 if (bp_parms[6].length)
7408 {
7409 if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
7410 {
7411 return _WRONG_MESSAGE_FORMAT;
7412 }
7413 switch (GET_WORD(global_config[0].info))
7414 {
7415 case 1:
7416 plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
7417 break;
7418 case 2:
7419 plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
7420 break;
7421 }
7422 }
7423 dbug(1, dprintf("call_dir=%04x", plci->call_dir));
7424
7425
7426 if ((GET_WORD(bp_parms[0].info) == B1_RTP)
7427 && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
7428 {
7429 plci->B1_resource = add_b1_facilities(plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE));
7430 adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
7431 cai[1] = plci->B1_resource;
7432 cai[2] = 0;
7433 cai[3] = 0;
7434 cai[4] = 0;
7435 PUT_WORD(&cai[5], plci->appl->MaxDataLength);
7436 for (i = 0; i < bp_parms[3].length; i++)
7437 cai[7 + i] = bp_parms[3].info[1 + i];
7438 cai[0] = 6 + bp_parms[3].length;
7439 add_p(plci, CAI, cai);
7440 return 0;
7441 }
7442
7443
7444 if ((GET_WORD(bp_parms[0].info) == B1_PIAFS)
7445 && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))
7446 {
7447 plci->B1_resource = add_b1_facilities(plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE));
7448 adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
7449 cai[1] = plci->B1_resource;
7450 cai[2] = 0;
7451 cai[3] = 0;
7452 cai[4] = 0;
7453 PUT_WORD(&cai[5], plci->appl->MaxDataLength);
7454 cai[0] = 6;
7455 add_p(plci, CAI, cai);
7456 return 0;
7457 }
7458
7459
7460 if ((GET_WORD(bp_parms[0].info) >= 32)
7461 || (!((1L << GET_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols)
7462 && ((GET_WORD(bp_parms[0].info) != 3)
7463 || !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols)
7464 || ((bp_parms[3].length != 0) && (GET_WORD(&bp_parms[3].info[1]) != 0) && (GET_WORD(&bp_parms[3].info[1]) != 56000)))))
7465 {
7466 return _B1_NOT_SUPPORTED;
7467 }
7468 plci->B1_resource = add_b1_facilities(plci, resource[GET_WORD(bp_parms[0].info)],
7469 (word)(b1_facilities & ~B1_FACILITY_VOICE));
7470 adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
7471 cai[0] = 6;
7472 cai[1] = plci->B1_resource;
7473 for (i = 2; i < sizeof(cai); i++) cai[i] = 0;
7474
7475 if ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
7476 || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
7477 || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))
7478 { /* B1 - modem */
7479 for (i = 0; i < 7; i++) mdm_cfg[i].length = 0;
7480
7481 if (bp_parms[3].length)
7482 {
7483 if (api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwww", mdm_cfg))
7484 {
7485 return (_WRONG_MESSAGE_FORMAT);
7486 }
7487
7488 cai[2] = 0; /* Bit rate for adaptation */
7489
7490 dbug(1, dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info)));
7491
7492 PUT_WORD(&cai[13], 0); /* Min Tx speed */
7493 PUT_WORD(&cai[15], GET_WORD(mdm_cfg[0].info)); /* Max Tx speed */
7494 PUT_WORD(&cai[17], 0); /* Min Rx speed */
7495 PUT_WORD(&cai[19], GET_WORD(mdm_cfg[0].info)); /* Max Rx speed */
7496
7497 cai[3] = 0; /* Async framing parameters */
7498 switch (GET_WORD(mdm_cfg[2].info))
7499 { /* Parity */
7500 case 1: /* odd parity */
7501 cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
7502 dbug(1, dprintf("MDM: odd parity"));
7503 break;
7504
7505 case 2: /* even parity */
7506 cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
7507 dbug(1, dprintf("MDM: even parity"));
7508 break;
7509
7510 default:
7511 dbug(1, dprintf("MDM: no parity"));
7512 break;
7513 }
7514
7515 switch (GET_WORD(mdm_cfg[3].info))
7516 { /* stop bits */
7517 case 1: /* 2 stop bits */
7518 cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
7519 dbug(1, dprintf("MDM: 2 stop bits"));
7520 break;
7521
7522 default:
7523 dbug(1, dprintf("MDM: 1 stop bit"));
7524 break;
7525 }
7526
7527 switch (GET_WORD(mdm_cfg[1].info))
7528 { /* char length */
7529 case 5:
7530 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
7531 dbug(1, dprintf("MDM: 5 bits"));
7532 break;
7533
7534 case 6:
7535 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
7536 dbug(1, dprintf("MDM: 6 bits"));
7537 break;
7538
7539 case 7:
7540 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
7541 dbug(1, dprintf("MDM: 7 bits"));
7542 break;
7543
7544 default:
7545 dbug(1, dprintf("MDM: 8 bits"));
7546 break;
7547 }
7548
7549 cai[7] = 0; /* Line taking options */
7550 cai[8] = 0; /* Modulation negotiation options */
7551 cai[9] = 0; /* Modulation options */
7552
7553 if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0))
7554 {
7555 cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION;
7556 dbug(1, dprintf("MDM: Reverse direction"));
7557 }
7558
7559 if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN)
7560 {
7561 cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN;
7562 dbug(1, dprintf("MDM: Disable retrain"));
7563 }
7564
7565 if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE)
7566 {
7567 cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE;
7568 dbug(1, dprintf("MDM: Disable ring tone"));
7569 }
7570
7571 if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_1800)
7572 {
7573 cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ;
7574 dbug(1, dprintf("MDM: 1800 guard tone"));
7575 }
7576 else if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_550)
7577 {
7578 cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ;
7579 dbug(1, dprintf("MDM: 550 guard tone"));
7580 }
7581
7582 if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100)
7583 {
7584 cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100;
7585 dbug(1, dprintf("MDM: V100"));
7586 }
7587 else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS)
7588 {
7589 cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS;
7590 dbug(1, dprintf("MDM: IN CLASS"));
7591 }
7592 else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED)
7593 {
7594 cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED;
7595 dbug(1, dprintf("MDM: DISABLED"));
7596 }
7597 cai[0] = 20;
7598
7599 if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18))
7600 && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */
7601 {
7602 plci->requested_options |= 1L << PRIVATE_V18;
7603 }
7604 if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */
7605 plci->requested_options |= 1L << PRIVATE_VOWN;
7606
7607 if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
7608 & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
7609 {
7610 if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwws", mdm_cfg))
7611 {
7612 i = 27;
7613 if (mdm_cfg[6].length >= 4)
7614 {
7615 d = GET_DWORD(&mdm_cfg[6].info[1]);
7616 cai[7] |= (byte) d; /* line taking options */
7617 cai[9] |= (byte)(d >> 8); /* modulation options */
7618 cai[++i] = (byte)(d >> 16); /* vown modulation options */
7619 cai[++i] = (byte)(d >> 24);
7620 if (mdm_cfg[6].length >= 8)
7621 {
7622 d = GET_DWORD(&mdm_cfg[6].info[5]);
7623 cai[10] |= (byte) d; /* disabled modulations mask */
7624 cai[11] |= (byte)(d >> 8);
7625 if (mdm_cfg[6].length >= 12)
7626 {
7627 d = GET_DWORD(&mdm_cfg[6].info[9]);
7628 cai[12] = (byte) d; /* enabled modulations mask */
7629 cai[++i] = (byte)(d >> 8); /* vown enabled modulations */
7630 cai[++i] = (byte)(d >> 16);
7631 cai[++i] = (byte)(d >> 24);
7632 cai[++i] = 0;
7633 if (mdm_cfg[6].length >= 14)
7634 {
7635 w = GET_WORD(&mdm_cfg[6].info[13]);
7636 if (w != 0)
7637 PUT_WORD(&cai[13], w); /* min tx speed */
7638 if (mdm_cfg[6].length >= 16)
7639 {
7640 w = GET_WORD(&mdm_cfg[6].info[15]);
7641 if (w != 0)
7642 PUT_WORD(&cai[15], w); /* max tx speed */
7643 if (mdm_cfg[6].length >= 18)
7644 {
7645 w = GET_WORD(&mdm_cfg[6].info[17]);
7646 if (w != 0)
7647 PUT_WORD(&cai[17], w); /* min rx speed */
7648 if (mdm_cfg[6].length >= 20)
7649 {
7650 w = GET_WORD(&mdm_cfg[6].info[19]);
7651 if (w != 0)
7652 PUT_WORD(&cai[19], w); /* max rx speed */
7653 if (mdm_cfg[6].length >= 22)
7654 {
7655 w = GET_WORD(&mdm_cfg[6].info[21]);
7656 cai[23] = (byte)(-((short) w)); /* transmit level */
7657 if (mdm_cfg[6].length >= 24)
7658 {
7659 w = GET_WORD(&mdm_cfg[6].info[23]);
7660 cai[22] |= (byte) w; /* info options mask */
7661 cai[21] |= (byte)(w >> 8); /* disabled symbol rates */
7662 }
7663 }
7664 }
7665 }
7666 }
7667 }
7668 }
7669 }
7670 }
7671 cai[27] = i - 27;
7672 i++;
7673 if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwwss", mdm_cfg))
7674 {
7675 if (!api_parse(&mdm_cfg[7].info[1], (word)mdm_cfg[7].length, "sss", mdm_cfg_v18))
7676 {
7677 for (n = 0; n < 3; n++)
7678 {
7679 cai[i] = (byte)(mdm_cfg_v18[n].length);
7680 for (j = 1; j < ((word)(cai[i] + 1)); j++)
7681 cai[i + j] = mdm_cfg_v18[n].info[j];
7682 i += cai[i] + 1;
7683 }
7684 }
7685 }
7686 cai[0] = (byte)(i - 1);
7687 }
7688 }
7689
7690 }
7691 }
7692 if (GET_WORD(bp_parms[0].info) == 2 || /* V.110 async */
7693 GET_WORD(bp_parms[0].info) == 3) /* V.110 sync */
7694 {
7695 if (bp_parms[3].length) {
7696 dbug(1, dprintf("V.110,%d", GET_WORD(&bp_parms[3].info[1])));
7697 switch (GET_WORD(&bp_parms[3].info[1])) { /* Rate */
7698 case 0:
7699 case 56000:
7700 if (GET_WORD(bp_parms[0].info) == 3) { /* V.110 sync 56k */
7701 dbug(1, dprintf("56k sync HSCX"));
7702 cai[1] = 8;
7703 cai[2] = 0;
7704 cai[3] = 0;
7705 }
7706 else if (GET_WORD(bp_parms[0].info) == 2) {
7707 dbug(1, dprintf("56k async DSP"));
7708 cai[2] = 9;
7709 }
7710 break;
7711 case 50: cai[2] = 1; break;
7712 case 75: cai[2] = 1; break;
7713 case 110: cai[2] = 1; break;
7714 case 150: cai[2] = 1; break;
7715 case 200: cai[2] = 1; break;
7716 case 300: cai[2] = 1; break;
7717 case 600: cai[2] = 1; break;
7718 case 1200: cai[2] = 2; break;
7719 case 2400: cai[2] = 3; break;
7720 case 4800: cai[2] = 4; break;
7721 case 7200: cai[2] = 10; break;
7722 case 9600: cai[2] = 5; break;
7723 case 12000: cai[2] = 13; break;
7724 case 24000: cai[2] = 0; break;
7725 case 14400: cai[2] = 11; break;
7726 case 19200: cai[2] = 6; break;
7727 case 28800: cai[2] = 12; break;
7728 case 38400: cai[2] = 7; break;
7729 case 48000: cai[2] = 8; break;
7730 case 76: cai[2] = 15; break; /* 75/1200 */
7731 case 1201: cai[2] = 14; break; /* 1200/75 */
7732 case 56001: cai[2] = 9; break; /* V.110 56000 */
7733
7734 default:
7735 return _B1_PARM_NOT_SUPPORTED;
7736 }
7737 cai[3] = 0;
7738 if (cai[1] == 13) /* v.110 async */
7739 {
7740 if (bp_parms[3].length >= 8)
7741 {
7742 switch (GET_WORD(&bp_parms[3].info[3]))
7743 { /* char length */
7744 case 5:
7745 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
7746 break;
7747 case 6:
7748 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
7749 break;
7750 case 7:
7751 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
7752 break;
7753 }
7754 switch (GET_WORD(&bp_parms[3].info[5]))
7755 { /* Parity */
7756 case 1: /* odd parity */
7757 cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
7758 break;
7759 case 2: /* even parity */
7760 cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
7761 break;
7762 }
7763 switch (GET_WORD(&bp_parms[3].info[7]))
7764 { /* stop bits */
7765 case 1: /* 2 stop bits */
7766 cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
7767 break;
7768 }
7769 }
7770 }
7771 }
7772 else if (cai[1] == 8 || GET_WORD(bp_parms[0].info) == 3) {
7773 dbug(1, dprintf("V.110 default 56k sync"));
7774 cai[1] = 8;
7775 cai[2] = 0;
7776 cai[3] = 0;
7777 }
7778 else {
7779 dbug(1, dprintf("V.110 default 9600 async"));
7780 cai[2] = 5;
7781 }
7782 }
7783 PUT_WORD(&cai[5], plci->appl->MaxDataLength);
7784 dbug(1, dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
7785/* HexDump ("CAI", sizeof(cai), &cai[0]); */
7786
7787 add_p(plci, CAI, cai);
7788 return 0;
7789}
7790
7791/*------------------------------------------------------------------*/
7792/* put parameter for b2 and B3 protocol in the parameter buffer */
7793/*------------------------------------------------------------------*/
7794
7795static word add_b23(PLCI *plci, API_PARSE *bp)
7796{
7797 word i, fax_control_bits;
7798 byte pos, len;
7799 byte SAPI = 0x40; /* default SAPI 16 for x.31 */
7800 API_PARSE bp_parms[8];
7801 API_PARSE *b1_config;
7802 API_PARSE *b2_config;
7803 API_PARSE b2_config_parms[8];
7804 API_PARSE *b3_config;
7805 API_PARSE b3_config_parms[6];
7806 API_PARSE global_config[2];
7807
7808 static byte llc[3] = {2,0,0};
7809 static byte dlc[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
7810 static byte nlc[256];
7811 static byte lli[12] = {1,1};
7812
7813 const byte llc2_out[] = {1,2,4,6,2,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};
7814 const byte llc2_in[] = {1,3,4,6,3,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};
7815
7816 const byte llc3[] = {4,3,2,2,6,6,0};
7817 const byte header[] = {0,2,3,3,0,0,0};
7818
7819 for (i = 0; i < 8; i++) bp_parms[i].length = 0;
7820 for (i = 0; i < 6; i++) b2_config_parms[i].length = 0;
7821 for (i = 0; i < 5; i++) b3_config_parms[i].length = 0;
7822
7823 lli[0] = 1;
7824 lli[1] = 1;
7825 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
7826 lli[1] |= 2;
7827 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
7828 lli[1] |= 4;
7829
7830 if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
7831 lli[1] |= 0x10;
7832 if (plci->rx_dma_descriptor <= 0) {
7833 plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic);
7834 if (plci->rx_dma_descriptor >= 0)
7835 plci->rx_dma_descriptor++;
7836 }
7837 if (plci->rx_dma_descriptor > 0) {
7838 lli[0] = 6;
7839 lli[1] |= 0x40;
7840 lli[2] = (byte)(plci->rx_dma_descriptor - 1);
7841 lli[3] = (byte)plci->rx_dma_magic;
7842 lli[4] = (byte)(plci->rx_dma_magic >> 8);
7843 lli[5] = (byte)(plci->rx_dma_magic >> 16);
7844 lli[6] = (byte)(plci->rx_dma_magic >> 24);
7845 }
7846 }
7847
7848 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
7849 lli[1] |= 0x20;
7850 }
7851
7852 dbug(1, dprintf("add_b23"));
7853 api_save_msg(bp, "s", &plci->B_protocol);
7854
7855 if (!bp->length && plci->tel)
7856 {
7857 plci->adv_nl = true;
7858 dbug(1, dprintf("Default adv.Nl"));
7859 add_p(plci, LLI, lli);
7860 plci->B2_prot = 1 /*XPARENT*/;
7861 plci->B3_prot = 0 /*XPARENT*/;
7862 llc[1] = 2;
7863 llc[2] = 4;
7864 add_p(plci, LLC, llc);
7865 dlc[0] = 2;
7866 PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
7867 add_p(plci, DLC, dlc);
7868 return 0;
7869 }
7870
7871 if (!bp->length) /*default*/
7872 {
7873 dbug(1, dprintf("ret default"));
7874 add_p(plci, LLI, lli);
7875 plci->B2_prot = 0 /*X.75 */;
7876 plci->B3_prot = 0 /*XPARENT*/;
7877 llc[1] = 1;
7878 llc[2] = 4;
7879 add_p(plci, LLC, llc);
7880 dlc[0] = 2;
7881 PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
7882 add_p(plci, DLC, dlc);
7883 return 0;
7884 }
7885 dbug(1, dprintf("b_prot_len=%d", (word)bp->length));
7886 if ((word)bp->length > 256) return _WRONG_MESSAGE_FORMAT;
7887
7888 if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
7889 {
7890 bp_parms[6].length = 0;
7891 if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
7892 {
7893 dbug(1, dprintf("b-form.!"));
7894 return _WRONG_MESSAGE_FORMAT;
7895 }
7896 }
7897 else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
7898 {
7899 dbug(1, dprintf("b-form.!"));
7900 return _WRONG_MESSAGE_FORMAT;
7901 }
7902
7903 if (plci->tel == ADV_VOICE) /* transparent B on advanced voice */
7904 {
7905 if (GET_WORD(bp_parms[1].info) != 1
7906 || GET_WORD(bp_parms[2].info) != 0) return _B2_NOT_SUPPORTED;
7907 plci->adv_nl = true;
7908 }
7909 else if (plci->tel) return _B2_NOT_SUPPORTED;
7910
7911
7912 if ((GET_WORD(bp_parms[1].info) == B2_RTP)
7913 && (GET_WORD(bp_parms[2].info) == B3_RTP)
7914 && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
7915 {
7916 add_p(plci, LLI, lli);
7917 plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
7918 plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
7919 llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? 14 : 13;
7920 llc[2] = 4;
7921 add_p(plci, LLC, llc);
7922 dlc[0] = 2;
7923 PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
7924 dlc[3] = 3; /* Addr A */
7925 dlc[4] = 1; /* Addr B */
7926 dlc[5] = 7; /* modulo mode */
7927 dlc[6] = 7; /* window size */
7928 dlc[7] = 0; /* XID len Lo */
7929 dlc[8] = 0; /* XID len Hi */
7930 for (i = 0; i < bp_parms[4].length; i++)
7931 dlc[9 + i] = bp_parms[4].info[1 + i];
7932 dlc[0] = (byte)(8 + bp_parms[4].length);
7933 add_p(plci, DLC, dlc);
7934 for (i = 0; i < bp_parms[5].length; i++)
7935 nlc[1 + i] = bp_parms[5].info[1 + i];
7936 nlc[0] = (byte)(bp_parms[5].length);
7937 add_p(plci, NLC, nlc);
7938 return 0;
7939 }
7940
7941
7942
7943 if ((GET_WORD(bp_parms[1].info) >= 32)
7944 || (!((1L << GET_WORD(bp_parms[1].info)) & plci->adapter->profile.B2_Protocols)
7945 && ((GET_WORD(bp_parms[1].info) != B2_PIAFS)
7946 || !(plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))))
7947
7948 {
7949 return _B2_NOT_SUPPORTED;
7950 }
7951 if ((GET_WORD(bp_parms[2].info) >= 32)
7952 || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols))
7953 {
7954 return _B3_NOT_SUPPORTED;
7955 }
7956 if ((GET_WORD(bp_parms[1].info) != B2_SDLC)
7957 && ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
7958 || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
7959 || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC)))
7960 {
7961 return (add_modem_b23(plci, bp_parms));
7962 }
7963
7964 add_p(plci, LLI, lli);
7965
7966 plci->B2_prot = (byte)GET_WORD(bp_parms[1].info);
7967 plci->B3_prot = (byte)GET_WORD(bp_parms[2].info);
7968 if (plci->B2_prot == 12) SAPI = 0; /* default SAPI D-channel */
7969
7970 if (bp_parms[6].length)
7971 {
7972 if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
7973 {
7974 return _WRONG_MESSAGE_FORMAT;
7975 }
7976 switch (GET_WORD(global_config[0].info))
7977 {
7978 case 1:
7979 plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
7980 break;
7981 case 2:
7982 plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
7983 break;
7984 }
7985 }
7986 dbug(1, dprintf("call_dir=%04x", plci->call_dir));
7987
7988
7989 if (plci->B2_prot == B2_PIAFS)
7990 llc[1] = PIAFS_CRC;
7991 else
7992/* IMPLEMENT_PIAFS */
7993 {
7994 llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
7995 llc2_out[GET_WORD(bp_parms[1].info)] : llc2_in[GET_WORD(bp_parms[1].info)];
7996 }
7997 llc[2] = llc3[GET_WORD(bp_parms[2].info)];
7998
7999 add_p(plci, LLC, llc);
8000
8001 dlc[0] = 2;
8002 PUT_WORD(&dlc[1], plci->appl->MaxDataLength +
8003 header[GET_WORD(bp_parms[2].info)]);
8004
8005 b1_config = &bp_parms[3];
8006 nlc[0] = 0;
8007 if (plci->B3_prot == 4
8008 || plci->B3_prot == 5)
8009 {
8010 for (i = 0; i < sizeof(T30_INFO); i++) nlc[i] = 0;
8011 nlc[0] = sizeof(T30_INFO);
8012 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
8013 ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI;
8014 ((T30_INFO *)&nlc[1])->rate_div_2400 = 0xff;
8015 if (b1_config->length >= 2)
8016 {
8017 ((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1]) / 2400);
8018 }
8019 }
8020 b2_config = &bp_parms[4];
8021
8022
8023 if (llc[1] == PIAFS_CRC)
8024 {
8025 if (plci->B3_prot != B3_TRANSPARENT)
8026 {
8027 return _B_STACK_NOT_SUPPORTED;
8028 }
8029 if (b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) {
8030 return _WRONG_MESSAGE_FORMAT;
8031 }
8032 PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
8033 dlc[3] = 0; /* Addr A */
8034 dlc[4] = 0; /* Addr B */
8035 dlc[5] = 0; /* modulo mode */
8036 dlc[6] = 0; /* window size */
8037 if (b2_config->length >= 7) {
8038 dlc[7] = 7;
8039 dlc[8] = 0;
8040 dlc[9] = b2_config_parms[0].info[0]; /* PIAFS protocol Speed configuration */
8041 dlc[10] = b2_config_parms[1].info[0]; /* V.42bis P0 */
8042 dlc[11] = b2_config_parms[1].info[1]; /* V.42bis P0 */
8043 dlc[12] = b2_config_parms[2].info[0]; /* V.42bis P1 */
8044 dlc[13] = b2_config_parms[2].info[1]; /* V.42bis P1 */
8045 dlc[14] = b2_config_parms[3].info[0]; /* V.42bis P2 */
8046 dlc[15] = b2_config_parms[3].info[1]; /* V.42bis P2 */
8047 dlc[0] = 15;
8048 if (b2_config->length >= 8) { /* PIAFS control abilities */
8049 dlc[7] = 10;
8050 dlc[16] = 2; /* Length of PIAFS extension */
8051 dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */
8052 dlc[18] = b2_config_parms[4].info[0]; /* value */
8053 dlc[0] = 18;
8054 }
8055 }
8056 else /* default values, 64K, variable, no compression */
8057 {
8058 dlc[7] = 7;
8059 dlc[8] = 0;
8060 dlc[9] = 0x03; /* PIAFS protocol Speed configuration */
8061 dlc[10] = 0x03; /* V.42bis P0 */
8062 dlc[11] = 0; /* V.42bis P0 */
8063 dlc[12] = 0; /* V.42bis P1 */
8064 dlc[13] = 0; /* V.42bis P1 */
8065 dlc[14] = 0; /* V.42bis P2 */
8066 dlc[15] = 0; /* V.42bis P2 */
8067 dlc[0] = 15;
8068 }
8069 add_p(plci, DLC, dlc);
8070 }
8071 else
8072
8073 if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS))
8074 {
8075 if (plci->B3_prot != B3_TRANSPARENT)
8076 return _B_STACK_NOT_SUPPORTED;
8077
8078 dlc[0] = 6;
8079 PUT_WORD(&dlc[1], GET_WORD(&dlc[1]) + 2);
8080 dlc[3] = 0x08;
8081 dlc[4] = 0x01;
8082 dlc[5] = 127;
8083 dlc[6] = 7;
8084 if (b2_config->length != 0)
8085 {
8086 if ((llc[1] == V120_V42BIS) && api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) {
8087 return _WRONG_MESSAGE_FORMAT;
8088 }
8089 dlc[3] = (byte)((b2_config->info[2] << 3) | ((b2_config->info[1] >> 5) & 0x04));
8090 dlc[4] = (byte)((b2_config->info[1] << 1) | 0x01);
8091 if (b2_config->info[3] != 128)
8092 {
8093 dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
8094 return _B2_PARM_NOT_SUPPORTED;
8095 }
8096 dlc[5] = (byte)(b2_config->info[3] - 1);
8097 dlc[6] = b2_config->info[4];
8098 if (llc[1] == V120_V42BIS) {
8099 if (b2_config->length >= 10) {
8100 dlc[7] = 6;
8101 dlc[8] = 0;
8102 dlc[9] = b2_config_parms[4].info[0];
8103 dlc[10] = b2_config_parms[4].info[1];
8104 dlc[11] = b2_config_parms[5].info[0];
8105 dlc[12] = b2_config_parms[5].info[1];
8106 dlc[13] = b2_config_parms[6].info[0];
8107 dlc[14] = b2_config_parms[6].info[1];
8108 dlc[0] = 14;
8109 dbug(1, dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
8110 dbug(1, dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
8111 dbug(1, dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
8112 }
8113 else {
8114 dlc[6] = 14;
8115 }
8116 }
8117 }
8118 }
8119 else
8120 {
8121 if (b2_config->length)
8122 {
8123 dbug(1, dprintf("B2-Config"));
8124 if (llc[1] == X75_V42BIS) {
8125 if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms))
8126 {
8127 return _WRONG_MESSAGE_FORMAT;
8128 }
8129 }
8130 else {
8131 if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms))
8132 {
8133 return _WRONG_MESSAGE_FORMAT;
8134 }
8135 }
8136 /* if B2 Protocol is LAPD, b2_config structure is different */
8137 if (llc[1] == 6)
8138 {
8139 dlc[0] = 4;
8140 if (b2_config->length >= 1) dlc[2] = b2_config->info[1]; /* TEI */
8141 else dlc[2] = 0x01;
8142 if ((b2_config->length >= 2) && (plci->B2_prot == 12))
8143 {
8144 SAPI = b2_config->info[2]; /* SAPI */
8145 }
8146 dlc[1] = SAPI;
8147 if ((b2_config->length >= 3) && (b2_config->info[3] == 128))
8148 {
8149 dlc[3] = 127; /* Mode */
8150 }
8151 else
8152 {
8153 dlc[3] = 7; /* Mode */
8154 }
8155
8156 if (b2_config->length >= 4) dlc[4] = b2_config->info[4]; /* Window */
8157 else dlc[4] = 1;
8158 dbug(1, dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
8159 if (b2_config->length > 5) return _B2_PARM_NOT_SUPPORTED;
8160 }
8161 else
8162 {
8163 dlc[0] = (byte)(b2_config_parms[4].length + 6);
8164 dlc[3] = b2_config->info[1];
8165 dlc[4] = b2_config->info[2];
8166 if (b2_config->info[3] != 8 && b2_config->info[3] != 128) {
8167 dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
8168 return _B2_PARM_NOT_SUPPORTED;
8169 }
8170
8171 dlc[5] = (byte)(b2_config->info[3] - 1);
8172 dlc[6] = b2_config->info[4];
8173 if (dlc[6] > dlc[5]) {
8174 dbug(1, dprintf("2D-dlc= %x %x %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4], dlc[5], dlc[6]));
8175 return _B2_PARM_NOT_SUPPORTED;
8176 }
8177
8178 if (llc[1] == X75_V42BIS) {
8179 if (b2_config->length >= 10) {
8180 dlc[7] = 6;
8181 dlc[8] = 0;
8182 dlc[9] = b2_config_parms[4].info[0];
8183 dlc[10] = b2_config_parms[4].info[1];
8184 dlc[11] = b2_config_parms[5].info[0];
8185 dlc[12] = b2_config_parms[5].info[1];
8186 dlc[13] = b2_config_parms[6].info[0];
8187 dlc[14] = b2_config_parms[6].info[1];
8188 dlc[0] = 14;
8189 dbug(1, dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
8190 dbug(1, dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
8191 dbug(1, dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
8192 }
8193 else {
8194 dlc[6] = 14;
8195 }
8196
8197 }
8198 else {
8199 PUT_WORD(&dlc[7], (word)b2_config_parms[4].length);
8200 for (i = 0; i < b2_config_parms[4].length; i++)
8201 dlc[11 + i] = b2_config_parms[4].info[1 + i];
8202 }
8203 }
8204 }
8205 }
8206 add_p(plci, DLC, dlc);
8207
8208 b3_config = &bp_parms[5];
8209 if (b3_config->length)
8210 {
8211 if (plci->B3_prot == 4
8212 || plci->B3_prot == 5)
8213 {
8214 if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms))
8215 {
8216 return _WRONG_MESSAGE_FORMAT;
8217 }
8218 i = GET_WORD((byte *)(b3_config_parms[0].info));
8219 ((T30_INFO *)&nlc[1])->resolution = (byte)(((i & 0x0001) ||
8220 ((plci->B3_prot == 4) && (((byte)(GET_WORD((byte *)b3_config_parms[1].info))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200 : 0);
8221 ((T30_INFO *)&nlc[1])->data_format = (byte)(GET_WORD((byte *)b3_config_parms[1].info));
8222 fax_control_bits = T30_CONTROL_BIT_ALL_FEATURES;
8223 if ((((T30_INFO *)&nlc[1])->rate_div_2400 != 0) && (((T30_INFO *)&nlc[1])->rate_div_2400 <= 6))
8224 fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_V34FAX;
8225 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
8226 {
8227
8228 if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
8229 & (1L << PRIVATE_FAX_PAPER_FORMATS))
8230 {
8231 ((T30_INFO *)&nlc[1])->resolution |= T30_RESOLUTION_R8_1540 |
8232 T30_RESOLUTION_R16_1540_OR_400 | T30_RESOLUTION_300_300 |
8233 T30_RESOLUTION_INCH_BASED | T30_RESOLUTION_METRIC_BASED;
8234 }
8235
8236 ((T30_INFO *)&nlc[1])->recording_properties =
8237 T30_RECORDING_WIDTH_ISO_A3 |
8238 (T30_RECORDING_LENGTH_UNLIMITED << 2) |
8239 (T30_MIN_SCANLINE_TIME_00_00_00 << 4);
8240 }
8241 if (plci->B3_prot == 5)
8242 {
8243 if (i & 0x0002) /* Accept incoming fax-polling requests */
8244 fax_control_bits |= T30_CONTROL_BIT_ACCEPT_POLLING;
8245 if (i & 0x2000) /* Do not use MR compression */
8246 fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_2D_CODING;
8247 if (i & 0x4000) /* Do not use MMR compression */
8248 fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_T6_CODING;
8249 if (i & 0x8000) /* Do not use ECM */
8250 fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_ECM;
8251 if (plci->fax_connect_info_length != 0)
8252 {
8253 ((T30_INFO *)&nlc[1])->resolution = ((T30_INFO *)plci->fax_connect_info_buffer)->resolution;
8254 ((T30_INFO *)&nlc[1])->data_format = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format;
8255 ((T30_INFO *)&nlc[1])->recording_properties = ((T30_INFO *)plci->fax_connect_info_buffer)->recording_properties;
8256 fax_control_bits |= GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) &
8257 (T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
8258 }
8259 }
8260 /* copy station id to NLC */
8261 for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
8262 {
8263 if (i < b3_config_parms[2].length)
8264 {
8265 ((T30_INFO *)&nlc[1])->station_id[i] = ((byte *)b3_config_parms[2].info)[1 + i];
8266 }
8267 else
8268 {
8269 ((T30_INFO *)&nlc[1])->station_id[i] = ' ';
8270 }
8271 }
8272 ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
8273 /* copy head line to NLC */
8274 if (b3_config_parms[3].length)
8275 {
8276
8277 pos = (byte)(fax_head_line_time(&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
8278 if (pos != 0)
8279 {
8280 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
8281 pos = 0;
8282 else
8283 {
8284 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8285 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8286 len = (byte)b3_config_parms[2].length;
8287 if (len > 20)
8288 len = 20;
8289 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
8290 {
8291 for (i = 0; i < len; i++)
8292 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1 + i];
8293 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8294 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8295 }
8296 }
8297 }
8298
8299 len = (byte)b3_config_parms[3].length;
8300 if (len > CAPI_MAX_HEAD_LINE_SPACE - pos)
8301 len = (byte)(CAPI_MAX_HEAD_LINE_SPACE - pos);
8302 ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
8303 nlc[0] += (byte)(pos + len);
8304 for (i = 0; i < len; i++)
8305 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[3].info)[1 + i];
8306 } else
8307 ((T30_INFO *)&nlc[1])->head_line_len = 0;
8308
8309 plci->nsf_control_bits = 0;
8310 if (plci->B3_prot == 5)
8311 {
8312 if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
8313 && (GET_WORD((byte *)b3_config_parms[1].info) & 0x8000)) /* Private SUB/SEP/PWD enable */
8314 {
8315 plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
8316 }
8317 if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
8318 && (GET_WORD((byte *)b3_config_parms[1].info) & 0x4000)) /* Private non-standard facilities enable */
8319 {
8320 plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD;
8321 }
8322 if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
8323 & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
8324 {
8325 if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
8326 & (1L << PRIVATE_FAX_SUB_SEP_PWD))
8327 {
8328 fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
8329 if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
8330 fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
8331 }
8332 len = nlc[0];
8333 pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
8334 if (pos < plci->fax_connect_info_length)
8335 {
8336 for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
8337 nlc[++len] = plci->fax_connect_info_buffer[pos++];
8338 }
8339 else
8340 nlc[++len] = 0;
8341 if (pos < plci->fax_connect_info_length)
8342 {
8343 for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
8344 nlc[++len] = plci->fax_connect_info_buffer[pos++];
8345 }
8346 else
8347 nlc[++len] = 0;
8348 if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
8349 & (1L << PRIVATE_FAX_NONSTANDARD))
8350 {
8351 if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0))
8352 {
8353 if ((plci->fax_connect_info_buffer[pos] >= 3) && (plci->fax_connect_info_buffer[pos + 1] >= 2))
8354 plci->nsf_control_bits = GET_WORD(&plci->fax_connect_info_buffer[pos + 2]);
8355 for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
8356 nlc[++len] = plci->fax_connect_info_buffer[pos++];
8357 }
8358 else
8359 {
8360 if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms))
8361 {
8362 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
8363 nlc[++len] = 0;
8364 }
8365 else
8366 {
8367 if ((b3_config_parms[4].length >= 3) && (b3_config_parms[4].info[1] >= 2))
8368 plci->nsf_control_bits = GET_WORD(&b3_config_parms[4].info[2]);
8369 nlc[++len] = (byte)(b3_config_parms[4].length);
8370 for (i = 0; i < b3_config_parms[4].length; i++)
8371 nlc[++len] = b3_config_parms[4].info[1 + i];
8372 }
8373 }
8374 }
8375 nlc[0] = len;
8376 if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
8377 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
8378 {
8379 ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG;
8380 }
8381 }
8382 }
8383
8384 PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
8385 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
8386 for (i = 0; i < len; i++)
8387 plci->fax_connect_info_buffer[i] = nlc[1 + i];
8388 ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0;
8389 i += ((T30_INFO *)&nlc[1])->head_line_len;
8390 while (i < nlc[0])
8391 plci->fax_connect_info_buffer[len++] = nlc[++i];
8392 plci->fax_connect_info_length = len;
8393 }
8394 else
8395 {
8396 nlc[0] = 14;
8397 if (b3_config->length != 16)
8398 return _B3_PARM_NOT_SUPPORTED;
8399 for (i = 0; i < 12; i++) nlc[1 + i] = b3_config->info[1 + i];
8400 if (GET_WORD(&b3_config->info[13]) != 8 && GET_WORD(&b3_config->info[13]) != 128)
8401 return _B3_PARM_NOT_SUPPORTED;
8402 nlc[13] = b3_config->info[13];
8403 if (GET_WORD(&b3_config->info[15]) >= nlc[13])
8404 return _B3_PARM_NOT_SUPPORTED;
8405 nlc[14] = b3_config->info[15];
8406 }
8407 }
8408 else
8409 {
8410 if (plci->B3_prot == 4
8411 || plci->B3_prot == 5 /*T.30 - FAX*/) return _B3_PARM_NOT_SUPPORTED;
8412 }
8413 add_p(plci, NLC, nlc);
8414 return 0;
8415}
8416
8417/*----------------------------------------------------------------*/
8418/* make the same as add_b23, but only for the modem related */
8419/* L2 and L3 B-Chan protocol. */
8420/* */
8421/* Enabled L2 and L3 Configurations: */
8422/* If L1 == Modem all negotiation */
8423/* only L2 == Modem with full negotiation is allowed */
8424/* If L1 == Modem async or sync */
8425/* only L2 == Transparent is allowed */
8426/* L3 == Modem or L3 == Transparent are allowed */
8427/* B2 Configuration for modem: */
8428/* word : enable/disable compression, bitoptions */
8429/* B3 Configuration for modem: */
8430/* empty */
8431/*----------------------------------------------------------------*/
8432static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms)
8433{
8434 static byte lli[12] = {1,1};
8435 static byte llc[3] = {2,0,0};
8436 static byte dlc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
8437 API_PARSE mdm_config[2];
8438 word i;
8439 word b2_config = 0;
8440
8441 for (i = 0; i < 2; i++) mdm_config[i].length = 0;
8442 for (i = 0; i < sizeof(dlc); i++) dlc[i] = 0;
8443
8444 if (((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
8445 && (GET_WORD(bp_parms[1].info) != B2_MODEM_EC_COMPRESSION))
8446 || ((GET_WORD(bp_parms[0].info) != B1_MODEM_ALL_NEGOTIATE)
8447 && (GET_WORD(bp_parms[1].info) != B2_TRANSPARENT)))
8448 {
8449 return (_B_STACK_NOT_SUPPORTED);
8450 }
8451 if ((GET_WORD(bp_parms[2].info) != B3_MODEM)
8452 && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT))
8453 {
8454 return (_B_STACK_NOT_SUPPORTED);
8455 }
8456
8457 plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
8458 plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
8459
8460 if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length)
8461 {
8462 if (api_parse(&bp_parms[4].info[1],
8463 (word)bp_parms[4].length, "w",
8464 mdm_config))
8465 {
8466 return (_WRONG_MESSAGE_FORMAT);
8467 }
8468 b2_config = GET_WORD(mdm_config[0].info);
8469 }
8470
8471 /* OK, L2 is modem */
8472
8473 lli[0] = 1;
8474 lli[1] = 1;
8475 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
8476 lli[1] |= 2;
8477 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
8478 lli[1] |= 4;
8479
8480 if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
8481 lli[1] |= 0x10;
8482 if (plci->rx_dma_descriptor <= 0) {
8483 plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic);
8484 if (plci->rx_dma_descriptor >= 0)
8485 plci->rx_dma_descriptor++;
8486 }
8487 if (plci->rx_dma_descriptor > 0) {
8488 lli[1] |= 0x40;
8489 lli[0] = 6;
8490 lli[2] = (byte)(plci->rx_dma_descriptor - 1);
8491 lli[3] = (byte)plci->rx_dma_magic;
8492 lli[4] = (byte)(plci->rx_dma_magic >> 8);
8493 lli[5] = (byte)(plci->rx_dma_magic >> 16);
8494 lli[6] = (byte)(plci->rx_dma_magic >> 24);
8495 }
8496 }
8497
8498 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
8499 lli[1] |= 0x20;
8500 }
8501
8502 llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
8503 /*V42*/ 10 : /*V42_IN*/ 9;
8504 llc[2] = 4; /* pass L3 always transparent */
8505 add_p(plci, LLI, lli);
8506 add_p(plci, LLC, llc);
8507 i = 1;
8508 PUT_WORD(&dlc[i], plci->appl->MaxDataLength);
8509 i += 2;
8510 if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION)
8511 {
8512 if (bp_parms[4].length)
8513 {
8514 dbug(1, dprintf("MDM b2_config=%02x", b2_config));
8515 dlc[i++] = 3; /* Addr A */
8516 dlc[i++] = 1; /* Addr B */
8517 dlc[i++] = 7; /* modulo mode */
8518 dlc[i++] = 7; /* window size */
8519 dlc[i++] = 0; /* XID len Lo */
8520 dlc[i++] = 0; /* XID len Hi */
8521
8522 if (b2_config & MDM_B2_DISABLE_V42bis)
8523 {
8524 dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS;
8525 }
8526 if (b2_config & MDM_B2_DISABLE_MNP)
8527 {
8528 dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5;
8529 }
8530 if (b2_config & MDM_B2_DISABLE_TRANS)
8531 {
8532 dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL;
8533 }
8534 if (b2_config & MDM_B2_DISABLE_V42)
8535 {
8536 dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT;
8537 }
8538 if (b2_config & MDM_B2_DISABLE_COMP)
8539 {
8540 dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION;
8541 }
8542 i++;
8543 }
8544 }
8545 else
8546 {
8547 dlc[i++] = 3; /* Addr A */
8548 dlc[i++] = 1; /* Addr B */
8549 dlc[i++] = 7; /* modulo mode */
8550 dlc[i++] = 7; /* window size */
8551 dlc[i++] = 0; /* XID len Lo */
8552 dlc[i++] = 0; /* XID len Hi */
8553 dlc[i++] = DLC_MODEMPROT_DISABLE_V42_V42BIS |
8554 DLC_MODEMPROT_DISABLE_MNP_MNP5 |
8555 DLC_MODEMPROT_DISABLE_V42_DETECT |
8556 DLC_MODEMPROT_DISABLE_COMPRESSION;
8557 }
8558 dlc[0] = (byte)(i - 1);
8559/* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
8560 add_p(plci, DLC, dlc);
8561 return (0);
8562}
8563
8564
8565/*------------------------------------------------------------------*/
8566/* send a request for the signaling entity */
8567/*------------------------------------------------------------------*/
8568
8569static void sig_req(PLCI *plci, byte req, byte Id)
8570{
8571 if (!plci) return;
8572 if (plci->adapter->adapter_disabled) return;
8573 dbug(1, dprintf("sig_req(%x)", req));
8574 if (req == REMOVE)
8575 plci->sig_remove_id = plci->Sig.Id;
8576 if (plci->req_in == plci->req_in_start) {
8577 plci->req_in += 2;
8578 plci->RBuffer[plci->req_in++] = 0;
8579 }
8580 PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2);
8581 plci->RBuffer[plci->req_in++] = Id; /* sig/nl flag */
8582 plci->RBuffer[plci->req_in++] = req; /* request */
8583 plci->RBuffer[plci->req_in++] = 0; /* channel */
8584 plci->req_in_start = plci->req_in;
8585}
8586
8587/*------------------------------------------------------------------*/
8588/* send a request for the network layer entity */
8589/*------------------------------------------------------------------*/
8590
8591static void nl_req_ncci(PLCI *plci, byte req, byte ncci)
8592{
8593 if (!plci) return;
8594 if (plci->adapter->adapter_disabled) return;
8595 dbug(1, dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci));
8596 if (req == REMOVE)
8597 {
8598 plci->nl_remove_id = plci->NL.Id;
8599 ncci_remove(plci, 0, (byte)(ncci != 0));
8600 ncci = 0;
8601 }
8602 if (plci->req_in == plci->req_in_start) {
8603 plci->req_in += 2;
8604 plci->RBuffer[plci->req_in++] = 0;
8605 }
8606 PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2);
8607 plci->RBuffer[plci->req_in++] = 1; /* sig/nl flag */
8608 plci->RBuffer[plci->req_in++] = req; /* request */
8609 plci->RBuffer[plci->req_in++] = plci->adapter->ncci_ch[ncci]; /* channel */
8610 plci->req_in_start = plci->req_in;
8611}
8612
8613static void send_req(PLCI *plci)
8614{
8615 ENTITY *e;
8616 word l;
8617/* word i; */
8618
8619 if (!plci) return;
8620 if (plci->adapter->adapter_disabled) return;
8621 channel_xmit_xon(plci);
8622
8623 /* if nothing to do, return */
8624 if (plci->req_in == plci->req_out) return;
8625 dbug(1, dprintf("send_req(in=%d,out=%d)", plci->req_in, plci->req_out));
8626
8627 if (plci->nl_req || plci->sig_req) return;
8628
8629 l = GET_WORD(&plci->RBuffer[plci->req_out]);
8630 plci->req_out += 2;
8631 plci->XData[0].P = &plci->RBuffer[plci->req_out];
8632 plci->req_out += l;
8633 if (plci->RBuffer[plci->req_out] == 1)
8634 {
8635 e = &plci->NL;
8636 plci->req_out++;
8637 e->Req = plci->nl_req = plci->RBuffer[plci->req_out++];
8638 e->ReqCh = plci->RBuffer[plci->req_out++];
8639 if (!(e->Id & 0x1f))
8640 {
8641 e->Id = NL_ID;
8642 plci->RBuffer[plci->req_out - 4] = CAI;
8643 plci->RBuffer[plci->req_out - 3] = 1;
8644 plci->RBuffer[plci->req_out - 2] = (plci->Sig.Id == 0xff) ? 0 : plci->Sig.Id;
8645 plci->RBuffer[plci->req_out - 1] = 0;
8646 l += 3;
8647 plci->nl_global_req = plci->nl_req;
8648 }
8649 dbug(1, dprintf("%x:NLREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh));
8650 }
8651 else
8652 {
8653 e = &plci->Sig;
8654 if (plci->RBuffer[plci->req_out])
8655 e->Id = plci->RBuffer[plci->req_out];
8656 plci->req_out++;
8657 e->Req = plci->sig_req = plci->RBuffer[plci->req_out++];
8658 e->ReqCh = plci->RBuffer[plci->req_out++];
8659 if (!(e->Id & 0x1f))
8660 plci->sig_global_req = plci->sig_req;
8661 dbug(1, dprintf("%x:SIGREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh));
8662 }
8663 plci->XData[0].PLength = l;
8664 e->X = plci->XData;
8665 plci->adapter->request(e);
8666 dbug(1, dprintf("send_ok"));
8667}
8668
8669static void send_data(PLCI *plci)
8670{
8671 DIVA_CAPI_ADAPTER *a;
8672 DATA_B3_DESC *data;
8673 NCCI *ncci_ptr;
8674 word ncci;
8675
8676 if (!plci->nl_req && plci->ncci_ring_list)
8677 {
8678 a = plci->adapter;
8679 ncci = plci->ncci_ring_list;
8680 do
8681 {
8682 ncci = a->ncci_next[ncci];
8683 ncci_ptr = &(a->ncci[ncci]);
8684 if (!(a->ncci_ch[ncci]
8685 && (a->ch_flow_control[a->ncci_ch[ncci]] & N_OK_FC_PENDING)))
8686 {
8687 if (ncci_ptr->data_pending)
8688 {
8689 if ((a->ncci_state[ncci] == CONNECTED)
8690 || (a->ncci_state[ncci] == INC_ACT_PENDING)
8691 || (plci->send_disc == ncci))
8692 {
8693 data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
8694 if ((plci->B2_prot == B2_V120_ASYNC)
8695 || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
8696 || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))
8697 {
8698 plci->NData[1].P = TransmitBufferGet(plci->appl, data->P);
8699 plci->NData[1].PLength = data->Length;
8700 if (data->Flags & 0x10)
8701 plci->NData[0].P = v120_break_header;
8702 else
8703 plci->NData[0].P = v120_default_header;
8704 plci->NData[0].PLength = 1;
8705 plci->NL.XNum = 2;
8706 plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA);
8707 }
8708 else
8709 {
8710 plci->NData[0].P = TransmitBufferGet(plci->appl, data->P);
8711 plci->NData[0].PLength = data->Length;
8712 if (data->Flags & 0x10)
8713 plci->NL.Req = plci->nl_req = (byte)N_UDATA;
8714
8715 else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01))
8716 plci->NL.Req = plci->nl_req = (byte)N_BDATA;
8717
8718 else
8719 plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA);
8720 }
8721 plci->NL.X = plci->NData;
8722 plci->NL.ReqCh = a->ncci_ch[ncci];
8723 dbug(1, dprintf("%x:DREQ(%x:%x)", a->Id, plci->NL.Id, plci->NL.Req));
8724 plci->data_sent = true;
8725 plci->data_sent_ptr = data->P;
8726 a->request(&plci->NL);
8727 }
8728 else {
8729 cleanup_ncci_data(plci, ncci);
8730 }
8731 }
8732 else if (plci->send_disc == ncci)
8733 {
8734 /* dprintf("N_DISC"); */
8735 plci->NData[0].PLength = 0;
8736 plci->NL.ReqCh = a->ncci_ch[ncci];
8737 plci->NL.Req = plci->nl_req = N_DISC;
8738 a->request(&plci->NL);
8739 plci->command = _DISCONNECT_B3_R;
8740 plci->send_disc = 0;
8741 }
8742 }
8743 } while (!plci->nl_req && (ncci != plci->ncci_ring_list));
8744 plci->ncci_ring_list = ncci;
8745 }
8746}
8747
8748static void listen_check(DIVA_CAPI_ADAPTER *a)
8749{
8750 word i, j;
8751 PLCI *plci;
8752 byte activnotifiedcalls = 0;
8753
8754 dbug(1, dprintf("listen_check(%d,%d)", a->listen_active, a->max_listen));
8755 if (!remove_started && !a->adapter_disabled)
8756 {
8757 for (i = 0; i < a->max_plci; i++)
8758 {
8759 plci = &(a->plci[i]);
8760 if (plci->notifiedcall) activnotifiedcalls++;
8761 }
8762 dbug(1, dprintf("listen_check(%d)", activnotifiedcalls));
8763
8764 for (i = a->listen_active; i < ((word)(a->max_listen + activnotifiedcalls)); i++) {
8765 if ((j = get_plci(a))) {
8766 a->listen_active++;
8767 plci = &a->plci[j - 1];
8768 plci->State = LISTENING;
8769
8770 add_p(plci, OAD, "\x01\xfd");
8771
8772 add_p(plci, KEY, "\x04\x43\x41\x32\x30");
8773
8774 add_p(plci, CAI, "\x01\xc0");
8775 add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
8776 add_p(plci, LLI, "\x01\xc4"); /* support Dummy CR FAC + MWI + SpoofNotify */
8777 add_p(plci, SHIFT | 6, NULL);
8778 add_p(plci, SIN, "\x02\x00\x00");
8779 plci->internal_command = LISTEN_SIG_ASSIGN_PEND; /* do indicate_req if OK */
8780 sig_req(plci, ASSIGN, DSIG_ID);
8781 send_req(plci);
8782 }
8783 }
8784 }
8785}
8786
8787/*------------------------------------------------------------------*/
8788/* functions for all parameters sent in INDs */
8789/*------------------------------------------------------------------*/
8790
8791static void IndParse(PLCI *plci, const word *parms_id, byte **parms, byte multiIEsize)
8792{
8793 word ploc; /* points to current location within packet */
8794 byte w;
8795 byte wlen;
8796 byte codeset, lock;
8797 byte *in;
8798 word i;
8799 word code;
8800 word mIEindex = 0;
8801 ploc = 0;
8802 codeset = 0;
8803 lock = 0;
8804
8805 in = plci->Sig.RBuffer->P;
8806 for (i = 0; i < parms_id[0]; i++) /* multiIE parms_id contains just the 1st */
8807 { /* element but parms array is larger */
8808 parms[i] = (byte *)"";
8809 }
8810 for (i = 0; i < multiIEsize; i++)
8811 {
8812 parms[i] = (byte *)"";
8813 }
8814
8815 while (ploc < plci->Sig.RBuffer->length - 1) {
8816
8817 /* read information element id and length */
8818 w = in[ploc];
8819
8820 if (w & 0x80) {
8821/* w &=0xf0; removed, cannot detect congestion levels */
8822/* upper 4 bit masked with w==SHIFT now */
8823 wlen = 0;
8824 }
8825 else {
8826 wlen = (byte)(in[ploc + 1] + 1);
8827 }
8828 /* check if length valid (not exceeding end of packet) */
8829 if ((ploc + wlen) > 270) return;
8830 if (lock & 0x80) lock &= 0x7f;
8831 else codeset = lock;
8832
8833 if ((w & 0xf0) == SHIFT) {
8834 codeset = in[ploc];
8835 if (!(codeset & 0x08)) lock = (byte)(codeset & 7);
8836 codeset &= 7;
8837 lock |= 0x80;
8838 }
8839 else {
8840 if (w == ESC && wlen >= 3) code = in[ploc + 2] | 0x800;
8841 else code = w;
8842 code |= (codeset << 8);
8843
8844 for (i = 1; i < parms_id[0] + 1 && parms_id[i] != code; i++);
8845
8846 if (i < parms_id[0] + 1) {
8847 if (!multiIEsize) { /* with multiIEs use next field index, */
8848 mIEindex = i - 1; /* with normal IEs use same index like parms_id */
8849 }
8850
8851 parms[mIEindex] = &in[ploc + 1];
8852 dbug(1, dprintf("mIE[%d]=0x%x", *parms[mIEindex], in[ploc]));
8853 if (parms_id[i] == OAD
8854 || parms_id[i] == CONN_NR
8855 || parms_id[i] == CAD) {
8856 if (in[ploc + 2] & 0x80) {
8857 in[ploc + 0] = (byte)(in[ploc + 1] + 1);
8858 in[ploc + 1] = (byte)(in[ploc + 2] & 0x7f);
8859 in[ploc + 2] = 0x80;
8860 parms[mIEindex] = &in[ploc];
8861 }
8862 }
8863 mIEindex++; /* effects multiIEs only */
8864 }
8865 }
8866
8867 ploc += (wlen + 1);
8868 }
8869 return;
8870}
8871
8872/*------------------------------------------------------------------*/
8873/* try to match a cip from received BC and HLC */
8874/*------------------------------------------------------------------*/
8875
8876static byte ie_compare(byte *ie1, byte *ie2)
8877{
8878 word i;
8879 if (!ie1 || !ie2) return false;
8880 if (!ie1[0]) return false;
8881 for (i = 0; i < (word)(ie1[0] + 1); i++) if (ie1[i] != ie2[i]) return false;
8882 return true;
8883}
8884
8885static word find_cip(DIVA_CAPI_ADAPTER *a, byte *bc, byte *hlc)
8886{
8887 word i;
8888 word j;
8889
8890 for (i = 9; i && !ie_compare(bc, cip_bc[i][a->u_law]); i--);
8891
8892 for (j = 16; j < 29 &&
8893 (!ie_compare(bc, cip_bc[j][a->u_law]) || !ie_compare(hlc, cip_hlc[j])); j++);
8894 if (j == 29) return i;
8895 return j;
8896}
8897
8898
8899static byte AddInfo(byte **add_i,
8900 byte **fty_i,
8901 byte *esc_chi,
8902 byte *facility)
8903{
8904 byte i;
8905 byte j;
8906 byte k;
8907 byte flen;
8908 byte len = 0;
8909 /* facility is a nested structure */
8910 /* FTY can be more than once */
8911
8912 if (esc_chi[0] && !(esc_chi[esc_chi[0]] & 0x7f))
8913 {
8914 add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */
8915 }
8916
8917 else
8918 {
8919 add_i[0] = (byte *)"";
8920 }
8921 if (!fty_i[0][0])
8922 {
8923 add_i[3] = (byte *)"";
8924 }
8925 else
8926 { /* facility array found */
8927 for (i = 0, j = 1; i < MAX_MULTI_IE && fty_i[i][0]; i++)
8928 {
8929 dbug(1, dprintf("AddIFac[%d]", fty_i[i][0]));
8930 len += fty_i[i][0];
8931 len += 2;
8932 flen = fty_i[i][0];
8933 facility[j++] = 0x1c; /* copy fac IE */
8934 for (k = 0; k <= flen; k++, j++)
8935 {
8936 facility[j] = fty_i[i][k];
8937/* dbug(1, dprintf("%x ",facility[j])); */
8938 }
8939 }
8940 facility[0] = len;
8941 add_i[3] = facility;
8942 }
8943/* dbug(1, dprintf("FacArrLen=%d ",len)); */
8944 len = add_i[0][0] + add_i[1][0] + add_i[2][0] + add_i[3][0];
8945 len += 4; /* calculate length of all */
8946 return (len);
8947}
8948
8949/*------------------------------------------------------------------*/
8950/* voice and codec features */
8951/*------------------------------------------------------------------*/
8952
8953static void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER *a)
8954{
8955 byte voice_chi[] = "\x02\x18\x01";
8956 byte channel;
8957
8958 channel = chi[chi[0]] & 0x3;
8959 dbug(1, dprintf("ExtDevON(Ch=0x%x)", channel));
8960 voice_chi[2] = (channel) ? channel : 1;
8961 add_p(plci, FTY, "\x02\x01\x07"); /* B On, default on 1 */
8962 add_p(plci, ESC, voice_chi); /* Channel */
8963 sig_req(plci, TEL_CTRL, 0);
8964 send_req(plci);
8965 if (a->AdvSignalPLCI)
8966 {
8967 adv_voice_write_coefs(a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION);
8968 }
8969}
8970
8971static void VoiceChannelOff(PLCI *plci)
8972{
8973 dbug(1, dprintf("ExtDevOFF"));
8974 add_p(plci, FTY, "\x02\x01\x08"); /* B Off */
8975 sig_req(plci, TEL_CTRL, 0);
8976 send_req(plci);
8977 if (plci->adapter->AdvSignalPLCI)
8978 {
8979 adv_voice_clear_config(plci->adapter->AdvSignalPLCI);
8980 }
8981}
8982
8983
8984static word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl,
8985 byte hook_listen)
8986{
8987 word j;
8988 PLCI *splci;
8989
8990 /* check if hardware supports handset with hook states (adv.codec) */
8991 /* or if just a on board codec is supported */
8992 /* the advanced codec plci is just for internal use */
8993
8994 /* diva Pro with on-board codec: */
8995 if (a->profile.Global_Options & HANDSET)
8996 {
8997 /* new call, but hook states are already signalled */
8998 if (a->AdvCodecFLAG)
8999 {
9000 if (a->AdvSignalAppl != appl || a->AdvSignalPLCI)
9001 {
9002 dbug(1, dprintf("AdvSigPlci=0x%x", a->AdvSignalPLCI));
9003 return 0x2001; /* codec in use by another application */
9004 }
9005 if (plci != NULL)
9006 {
9007 a->AdvSignalPLCI = plci;
9008 plci->tel = ADV_VOICE;
9009 }
9010 return 0; /* adv codec still used */
9011 }
9012 if ((j = get_plci(a)))
9013 {
9014 splci = &a->plci[j - 1];
9015 splci->tel = CODEC_PERMANENT;
9016 /* hook_listen indicates if a facility_req with handset/hook support */
9017 /* was sent. Otherwise if just a call on an external device was made */
9018 /* the codec will be used but the hook info will be discarded (just */
9019 /* the external controller is in use */
9020 if (hook_listen) splci->State = ADVANCED_VOICE_SIG;
9021 else
9022 {
9023 splci->State = ADVANCED_VOICE_NOSIG;
9024 if (plci)
9025 {
9026 plci->spoofed_msg = SPOOFING_REQUIRED;
9027 }
9028 /* indicate D-ch connect if */
9029 } /* codec is connected OK */
9030 if (plci != NULL)
9031 {
9032 a->AdvSignalPLCI = plci;
9033 plci->tel = ADV_VOICE;
9034 }
9035 a->AdvSignalAppl = appl;
9036 a->AdvCodecFLAG = true;
9037 a->AdvCodecPLCI = splci;
9038 add_p(splci, CAI, "\x01\x15");
9039 add_p(splci, LLI, "\x01\x00");
9040 add_p(splci, ESC, "\x02\x18\x00");
9041 add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
9042 splci->internal_command = PERM_COD_ASSIGN;
9043 dbug(1, dprintf("Codec Assign"));
9044 sig_req(splci, ASSIGN, DSIG_ID);
9045 send_req(splci);
9046 }
9047 else
9048 {
9049 return 0x2001; /* wrong state, no more plcis */
9050 }
9051 }
9052 else if (a->profile.Global_Options & ON_BOARD_CODEC)
9053 {
9054 if (hook_listen) return 0x300B; /* Facility not supported */
9055 /* no hook with SCOM */
9056 if (plci != NULL) plci->tel = CODEC;
9057 dbug(1, dprintf("S/SCOM codec"));
9058 /* first time we use the scom-s codec we must shut down the internal */
9059 /* handset application of the card. This can be done by an assign with */
9060 /* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/
9061 if (!a->scom_appl_disable) {
9062 if ((j = get_plci(a))) {
9063 splci = &a->plci[j - 1];
9064 add_p(splci, CAI, "\x01\x80");
9065 add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
9066 sig_req(splci, ASSIGN, 0xC0); /* 0xc0 is the TEL_ID */
9067 send_req(splci);
9068 a->scom_appl_disable = true;
9069 }
9070 else{
9071 return 0x2001; /* wrong state, no more plcis */
9072 }
9073 }
9074 }
9075 else return 0x300B; /* Facility not supported */
9076
9077 return 0;
9078}
9079
9080
9081static void CodecIdCheck(DIVA_CAPI_ADAPTER *a, PLCI *plci)
9082{
9083
9084 dbug(1, dprintf("CodecIdCheck"));
9085
9086 if (a->AdvSignalPLCI == plci)
9087 {
9088 dbug(1, dprintf("PLCI owns codec"));
9089 VoiceChannelOff(a->AdvCodecPLCI);
9090 if (a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG)
9091 {
9092 dbug(1, dprintf("remove temp codec PLCI"));
9093 plci_remove(a->AdvCodecPLCI);
9094 a->AdvCodecFLAG = 0;
9095 a->AdvCodecPLCI = NULL;
9096 a->AdvSignalAppl = NULL;
9097 }
9098 a->AdvSignalPLCI = NULL;
9099 }
9100}
9101
9102/* -------------------------------------------------------------------
9103 Ask for physical address of card on PCI bus
9104 ------------------------------------------------------------------- */
9105static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *a,
9106 IDI_SYNC_REQ *preq) {
9107 a->sdram_bar = 0;
9108 if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) {
9109 ENTITY *e = (ENTITY *)preq;
9110
9111 e->user[0] = a->Id - 1;
9112 preq->xdi_sdram_bar.info.bar = 0;
9113 preq->xdi_sdram_bar.Req = 0;
9114 preq->xdi_sdram_bar.Rc = IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR;
9115
9116 (*(a->request))(e);
9117
9118 a->sdram_bar = preq->xdi_sdram_bar.info.bar;
9119 dbug(3, dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar));
9120 }
9121}
9122
9123/* -------------------------------------------------------------------
9124 Ask XDI about extended features
9125 ------------------------------------------------------------------- */
9126static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a) {
9127 IDI_SYNC_REQ *preq;
9128 char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)];
9129
9130 char features[4];
9131 preq = (IDI_SYNC_REQ *)&buffer[0];
9132
9133 if (!diva_xdi_extended_features) {
9134 ENTITY *e = (ENTITY *)preq;
9135 diva_xdi_extended_features |= 0x80000000;
9136
9137 e->user[0] = a->Id - 1;
9138 preq->xdi_extended_features.Req = 0;
9139 preq->xdi_extended_features.Rc = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
9140 preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
9141 preq->xdi_extended_features.info.features = &features[0];
9142
9143 (*(a->request))(e);
9144
9145 if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) {
9146 /*
9147 Check features located in the byte '0'
9148 */
9149 if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) {
9150 diva_xdi_extended_features |= DIVA_CAPI_USE_CMA;
9151 }
9152 if (features[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA) {
9153 diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_RX_DMA;
9154 dbug(1, dprintf("XDI provides RxDMA"));
9155 }
9156 if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) {
9157 diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR;
9158 }
9159 if (features[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC) {
9160 diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL;
9161 dbug(3, dprintf("XDI provides NO_CANCEL_RC feature"));
9162 }
9163
9164 }
9165 }
9166
9167 diva_ask_for_xdi_sdram_bar(a, preq);
9168}
9169
9170/*------------------------------------------------------------------*/
9171/* automatic law */
9172/*------------------------------------------------------------------*/
9173/* called from OS specific part after init time to get the Law */
9174/* a-law (Euro) and u-law (us,japan) use different BCs in the Setup message */
9175void AutomaticLaw(DIVA_CAPI_ADAPTER *a)
9176{
9177 word j;
9178 PLCI *splci;
9179
9180 if (a->automatic_law) {
9181 return;
9182 }
9183 if ((j = get_plci(a))) {
9184 diva_get_extended_adapter_features(a);
9185 splci = &a->plci[j - 1];
9186 a->automatic_lawPLCI = splci;
9187 a->automatic_law = 1;
9188 add_p(splci, CAI, "\x01\x80");
9189 add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
9190 splci->internal_command = USELAW_REQ;
9191 splci->command = 0;
9192 splci->number = 0;
9193 sig_req(splci, ASSIGN, DSIG_ID);
9194 send_req(splci);
9195 }
9196}
9197
9198/* called from OS specific part if an application sends an Capi20Release */
9199word CapiRelease(word Id)
9200{
9201 word i, j, appls_found;
9202 PLCI *plci;
9203 APPL *this;
9204 DIVA_CAPI_ADAPTER *a;
9205
9206 if (!Id)
9207 {
9208 dbug(0, dprintf("A: CapiRelease(Id==0)"));
9209 return (_WRONG_APPL_ID);
9210 }
9211
9212 this = &application[Id - 1]; /* get application pointer */
9213
9214 for (i = 0, appls_found = 0; i < max_appl; i++)
9215 {
9216 if (application[i].Id) /* an application has been found */
9217 {
9218 appls_found++;
9219 }
9220 }
9221
9222 for (i = 0; i < max_adapter; i++) /* scan all adapters... */
9223 {
9224 a = &adapter[i];
9225 if (a->request)
9226 {
9227 a->Info_Mask[Id - 1] = 0;
9228 a->CIP_Mask[Id - 1] = 0;
9229 a->Notification_Mask[Id - 1] = 0;
9230 a->codec_listen[Id - 1] = NULL;
9231 a->requested_options_table[Id - 1] = 0;
9232 for (j = 0; j < a->max_plci; j++) /* and all PLCIs connected */
9233 { /* with this application */
9234 plci = &a->plci[j];
9235 if (plci->Id) /* if plci owns no application */
9236 { /* it may be not jet connected */
9237 if (plci->State == INC_CON_PENDING
9238 || plci->State == INC_CON_ALERT)
9239 {
9240 if (test_bit(Id - 1, plci->c_ind_mask_table))
9241 {
9242 __clear_bit(Id - 1, plci->c_ind_mask_table);
9243 if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
9244 {
9245 sig_req(plci, HANGUP, 0);
9246 send_req(plci);
9247 plci->State = OUTG_DIS_PENDING;
9248 }
9249 }
9250 }
9251 if (test_bit(Id - 1, plci->c_ind_mask_table))
9252 {
9253 __clear_bit(Id - 1, plci->c_ind_mask_table);
9254 if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
9255 {
9256 if (!plci->appl)
9257 {
9258 plci_remove(plci);
9259 plci->State = IDLE;
9260 }
9261 }
9262 }
9263 if (plci->appl == this)
9264 {
9265 plci->appl = NULL;
9266 plci_remove(plci);
9267 plci->State = IDLE;
9268 }
9269 }
9270 }
9271 listen_check(a);
9272
9273 if (a->flag_dynamic_l1_down)
9274 {
9275 if (appls_found == 1) /* last application does a capi release */
9276 {
9277 if ((j = get_plci(a)))
9278 {
9279 plci = &a->plci[j - 1];
9280 plci->command = 0;
9281 add_p(plci, OAD, "\x01\xfd");
9282 add_p(plci, CAI, "\x01\x80");
9283 add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
9284 add_p(plci, SHIFT | 6, NULL);
9285 add_p(plci, SIN, "\x02\x00\x00");
9286 plci->internal_command = REM_L1_SIG_ASSIGN_PEND;
9287 sig_req(plci, ASSIGN, DSIG_ID);
9288 add_p(plci, FTY, "\x02\xff\x06"); /* l1 down */
9289 sig_req(plci, SIG_CTRL, 0);
9290 send_req(plci);
9291 }
9292 }
9293 }
9294 if (a->AdvSignalAppl == this)
9295 {
9296 this->NullCREnable = false;
9297 if (a->AdvCodecPLCI)
9298 {
9299 plci_remove(a->AdvCodecPLCI);
9300 a->AdvCodecPLCI->tel = 0;
9301 a->AdvCodecPLCI->adv_nl = 0;
9302 }
9303 a->AdvSignalAppl = NULL;
9304 a->AdvSignalPLCI = NULL;
9305 a->AdvCodecFLAG = 0;
9306 a->AdvCodecPLCI = NULL;
9307 }
9308 }
9309 }
9310
9311 this->Id = 0;
9312
9313 return GOOD;
9314}
9315
9316static word plci_remove_check(PLCI *plci)
9317{
9318 if (!plci) return true;
9319 if (!plci->NL.Id && bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
9320 {
9321 if (plci->Sig.Id == 0xff)
9322 plci->Sig.Id = 0;
9323 if (!plci->Sig.Id)
9324 {
9325 dbug(1, dprintf("plci_remove_complete(%x)", plci->Id));
9326 dbug(1, dprintf("tel=0x%x,Sig=0x%x", plci->tel, plci->Sig.Id));
9327 if (plci->Id)
9328 {
9329 CodecIdCheck(plci->adapter, plci);
9330 clear_b1_config(plci);
9331 ncci_remove(plci, 0, false);
9332 plci_free_msg_in_queue(plci);
9333 channel_flow_control_remove(plci);
9334 plci->Id = 0;
9335 plci->State = IDLE;
9336 plci->channels = 0;
9337 plci->appl = NULL;
9338 plci->notifiedcall = 0;
9339 }
9340 listen_check(plci->adapter);
9341 return true;
9342 }
9343 }
9344 return false;
9345}
9346
9347
9348/*------------------------------------------------------------------*/
9349
9350static byte plci_nl_busy(PLCI *plci)
9351{
9352 /* only applicable for non-multiplexed protocols */
9353 return (plci->nl_req
9354 || (plci->ncci_ring_list
9355 && plci->adapter->ncci_ch[plci->ncci_ring_list]
9356 && (plci->adapter->ch_flow_control[plci->adapter->ncci_ch[plci->ncci_ring_list]] & N_OK_FC_PENDING)));
9357}
9358
9359
9360/*------------------------------------------------------------------*/
9361/* DTMF facilities */
9362/*------------------------------------------------------------------*/
9363
9364
9365static struct
9366{
9367 byte send_mask;
9368 byte listen_mask;
9369 byte character;
9370 byte code;
9371} dtmf_digit_map[] =
9372{
9373 { 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK },
9374 { 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR },
9375 { 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0 },
9376 { 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1 },
9377 { 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2 },
9378 { 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3 },
9379 { 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4 },
9380 { 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5 },
9381 { 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6 },
9382 { 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7 },
9383 { 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8 },
9384 { 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9 },
9385 { 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A },
9386 { 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B },
9387 { 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C },
9388 { 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D },
9389 { 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A },
9390 { 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B },
9391 { 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C },
9392 { 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D },
9393
9394 { 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE },
9395 { 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE },
9396 { 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE },
9397 { 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE },
9398 { 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE },
9399 { 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE },
9400 { 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE },
9401 { 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE },
9402 { 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE },
9403 { 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE },
9404 { 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE },
9405 { 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE },
9406 { 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE },
9407 { 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE },
9408 { 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE },
9409 { 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE },
9410 { 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE },
9411 { 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE },
9412 { 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE },
9413 { 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE },
9414 { 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE },
9415 { 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE },
9416 { 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE },
9417 { 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL },
9418 { 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE },
9419 { 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE },
9420 { 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE },
9421 { 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE },
9422 { 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE },
9423 { 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE },
9424 { 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE },
9425 { 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE },
9426 { 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE },
9427 { 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS },
9428 { 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID },
9429 { 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH },
9430 { 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390 },
9431 { 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1 },
9432 { 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2 },
9433 { 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3 },
9434 { 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4 },
9435 { 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5 },
9436 { 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6 },
9437 { 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7 },
9438 { 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8 },
9439 { 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9 },
9440 { 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0 },
9441 { 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1 },
9442 { 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2 },
9443 { 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP },
9444 { 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1 },
9445 { 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST },
9446
9447};
9448
9449#define DTMF_DIGIT_MAP_ENTRIES ARRAY_SIZE(dtmf_digit_map)
9450
9451
9452static void dtmf_enable_receiver(PLCI *plci, byte enable_mask)
9453{
9454 word min_digit_duration, min_gap_duration;
9455
9456 dbug(1, dprintf("[%06lx] %s,%d: dtmf_enable_receiver %02x",
9457 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
9458 (char *)(FILE_), __LINE__, enable_mask));
9459
9460 if (enable_mask != 0)
9461 {
9462 min_digit_duration = (plci->dtmf_rec_pulse_ms == 0) ? 40 : plci->dtmf_rec_pulse_ms;
9463 min_gap_duration = (plci->dtmf_rec_pause_ms == 0) ? 40 : plci->dtmf_rec_pause_ms;
9464 plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER;
9465 PUT_WORD(&plci->internal_req_buffer[1], min_digit_duration);
9466 PUT_WORD(&plci->internal_req_buffer[3], min_gap_duration);
9467 plci->NData[0].PLength = 5;
9468
9469 PUT_WORD(&plci->internal_req_buffer[5], INTERNAL_IND_BUFFER_SIZE);
9470 plci->NData[0].PLength += 2;
9471 capidtmf_recv_enable(&(plci->capidtmf_state), min_digit_duration, min_gap_duration);
9472
9473 }
9474 else
9475 {
9476 plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER;
9477 plci->NData[0].PLength = 1;
9478
9479 capidtmf_recv_disable(&(plci->capidtmf_state));
9480
9481 }
9482 plci->NData[0].P = plci->internal_req_buffer;
9483 plci->NL.X = plci->NData;
9484 plci->NL.ReqCh = 0;
9485 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
9486 plci->adapter->request(&plci->NL);
9487}
9488
9489
9490static void dtmf_send_digits(PLCI *plci, byte *digit_buffer, word digit_count)
9491{
9492 word w, i;
9493
9494 dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_digits %d",
9495 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
9496 (char *)(FILE_), __LINE__, digit_count));
9497
9498 plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_SEND_DIGITS;
9499 w = (plci->dtmf_send_pulse_ms == 0) ? 40 : plci->dtmf_send_pulse_ms;
9500 PUT_WORD(&plci->internal_req_buffer[1], w);
9501 w = (plci->dtmf_send_pause_ms == 0) ? 40 : plci->dtmf_send_pause_ms;
9502 PUT_WORD(&plci->internal_req_buffer[3], w);
9503 for (i = 0; i < digit_count; i++)
9504 {
9505 w = 0;
9506 while ((w < DTMF_DIGIT_MAP_ENTRIES)
9507 && (digit_buffer[i] != dtmf_digit_map[w].character))
9508 {
9509 w++;
9510 }
9511 plci->internal_req_buffer[5 + i] = (w < DTMF_DIGIT_MAP_ENTRIES) ?
9512 dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR;
9513 }
9514 plci->NData[0].PLength = 5 + digit_count;
9515 plci->NData[0].P = plci->internal_req_buffer;
9516 plci->NL.X = plci->NData;
9517 plci->NL.ReqCh = 0;
9518 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
9519 plci->adapter->request(&plci->NL);
9520}
9521
9522
9523static void dtmf_rec_clear_config(PLCI *plci)
9524{
9525
9526 dbug(1, dprintf("[%06lx] %s,%d: dtmf_rec_clear_config",
9527 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
9528 (char *)(FILE_), __LINE__));
9529
9530 plci->dtmf_rec_active = 0;
9531 plci->dtmf_rec_pulse_ms = 0;
9532 plci->dtmf_rec_pause_ms = 0;
9533
9534 capidtmf_init(&(plci->capidtmf_state), plci->adapter->u_law);
9535
9536}
9537
9538
9539static void dtmf_send_clear_config(PLCI *plci)
9540{
9541
9542 dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_clear_config",
9543 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
9544 (char *)(FILE_), __LINE__));
9545
9546 plci->dtmf_send_requests = 0;
9547 plci->dtmf_send_pulse_ms = 0;
9548 plci->dtmf_send_pause_ms = 0;
9549}
9550
9551
9552static void dtmf_prepare_switch(dword Id, PLCI *plci)
9553{
9554
9555 dbug(1, dprintf("[%06lx] %s,%d: dtmf_prepare_switch",
9556 UnMapId(Id), (char *)(FILE_), __LINE__));
9557
9558 while (plci->dtmf_send_requests != 0)
9559 dtmf_confirmation(Id, plci);
9560}
9561
9562
9563static word dtmf_save_config(dword Id, PLCI *plci, byte Rc)
9564{
9565
9566 dbug(1, dprintf("[%06lx] %s,%d: dtmf_save_config %02x %d",
9567 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
9568
9569 return (GOOD);
9570}
9571
9572
9573static word dtmf_restore_config(dword Id, PLCI *plci, byte Rc)
9574{
9575 word Info;
9576
9577 dbug(1, dprintf("[%06lx] %s,%d: dtmf_restore_config %02x %d",
9578 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
9579
9580 Info = GOOD;
9581 if (plci->B1_facilities & B1_FACILITY_DTMFR)
9582 {
9583 switch (plci->adjust_b_state)
9584 {
9585 case ADJUST_B_RESTORE_DTMF_1:
9586 plci->internal_command = plci->adjust_b_command;
9587 if (plci_nl_busy(plci))
9588 {
9589 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
9590 break;
9591 }
9592 dtmf_enable_receiver(plci, plci->dtmf_rec_active);
9593 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2;
9594 break;
9595 case ADJUST_B_RESTORE_DTMF_2:
9596 if ((Rc != OK) && (Rc != OK_FC))
9597 {
9598 dbug(1, dprintf("[%06lx] %s,%d: Reenable DTMF receiver failed %02x",
9599 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
9600 Info = _WRONG_STATE;
9601 break;
9602 }
9603 break;
9604 }
9605 }
9606 return (Info);
9607}
9608
9609
9610static void dtmf_command(dword Id, PLCI *plci, byte Rc)
9611{
9612 word internal_command, Info;
9613 byte mask;
9614 byte result[4];
9615
9616 dbug(1, dprintf("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d",
9617 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
9618 plci->dtmf_cmd, plci->dtmf_rec_pulse_ms, plci->dtmf_rec_pause_ms,
9619 plci->dtmf_send_pulse_ms, plci->dtmf_send_pause_ms));
9620
9621 Info = GOOD;
9622 result[0] = 2;
9623 PUT_WORD(&result[1], DTMF_SUCCESS);
9624 internal_command = plci->internal_command;
9625 plci->internal_command = 0;
9626 mask = 0x01;
9627 switch (plci->dtmf_cmd)
9628 {
9629
9630 case DTMF_LISTEN_TONE_START:
9631 mask <<= 1; /* fall through */
9632 case DTMF_LISTEN_MF_START:
9633 mask <<= 1; /* fall through */
9634
9635 case DTMF_LISTEN_START:
9636 switch (internal_command)
9637 {
9638 default:
9639 adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
9640 B1_FACILITY_DTMFR), DTMF_COMMAND_1);
9641 /* fall through */
9642 case DTMF_COMMAND_1:
9643 if (adjust_b_process(Id, plci, Rc) != GOOD)
9644 {
9645 dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
9646 UnMapId(Id), (char *)(FILE_), __LINE__));
9647 Info = _FACILITY_NOT_SUPPORTED;
9648 break;
9649 }
9650 if (plci->internal_command)
9651 return;
9652 /* fall through */
9653 case DTMF_COMMAND_2:
9654 if (plci_nl_busy(plci))
9655 {
9656 plci->internal_command = DTMF_COMMAND_2;
9657 return;
9658 }
9659 plci->internal_command = DTMF_COMMAND_3;
9660 dtmf_enable_receiver(plci, (byte)(plci->dtmf_rec_active | mask));
9661 return;
9662 case DTMF_COMMAND_3:
9663 if ((Rc != OK) && (Rc != OK_FC))
9664 {
9665 dbug(1, dprintf("[%06lx] %s,%d: Enable DTMF receiver failed %02x",
9666 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
9667 Info = _FACILITY_NOT_SUPPORTED;
9668 break;
9669 }
9670
9671 plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE;
9672
9673 plci->dtmf_rec_active |= mask;
9674 break;
9675 }
9676 break;
9677
9678
9679 case DTMF_LISTEN_TONE_STOP:
9680 mask <<= 1; /* fall through */
9681 case DTMF_LISTEN_MF_STOP:
9682 mask <<= 1; /* fall through */
9683
9684 case DTMF_LISTEN_STOP:
9685 switch (internal_command)
9686 {
9687 default:
9688 plci->dtmf_rec_active &= ~mask;
9689 if (plci->dtmf_rec_active)
9690 break;
9691/*
9692 case DTMF_COMMAND_1:
9693 if (plci->dtmf_rec_active)
9694 {
9695 if (plci_nl_busy (plci))
9696 {
9697 plci->internal_command = DTMF_COMMAND_1;
9698 return;
9699 }
9700 plci->dtmf_rec_active &= ~mask;
9701 plci->internal_command = DTMF_COMMAND_2;
9702 dtmf_enable_receiver (plci, false);
9703 return;
9704 }
9705 Rc = OK;
9706 case DTMF_COMMAND_2:
9707 if ((Rc != OK) && (Rc != OK_FC))
9708 {
9709 dbug (1, dprintf("[%06lx] %s,%d: Disable DTMF receiver failed %02x",
9710 UnMapId (Id), (char far *)(FILE_), __LINE__, Rc));
9711 Info = _FACILITY_NOT_SUPPORTED;
9712 break;
9713 }
9714*/
9715 adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
9716 ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3);
9717 /* fall through */
9718 case DTMF_COMMAND_3:
9719 if (adjust_b_process(Id, plci, Rc) != GOOD)
9720 {
9721 dbug(1, dprintf("[%06lx] %s,%d: Unload DTMF failed",
9722 UnMapId(Id), (char *)(FILE_), __LINE__));
9723 Info = _FACILITY_NOT_SUPPORTED;
9724 break;
9725 }
9726 if (plci->internal_command)
9727 return;
9728 break;
9729 }
9730 break;
9731
9732
9733 case DTMF_SEND_TONE:
9734 mask <<= 1; /* fall through */
9735 case DTMF_SEND_MF:
9736 mask <<= 1; /* fall through */
9737
9738 case DTMF_DIGITS_SEND:
9739 switch (internal_command)
9740 {
9741 default:
9742 adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
9743 ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)),
9744 DTMF_COMMAND_1);
9745 /* fall through */
9746 case DTMF_COMMAND_1:
9747 if (adjust_b_process(Id, plci, Rc) != GOOD)
9748 {
9749 dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
9750 UnMapId(Id), (char *)(FILE_), __LINE__));
9751 Info = _FACILITY_NOT_SUPPORTED;
9752 break;
9753 }
9754 if (plci->internal_command)
9755 return;
9756 /* fall through */
9757 case DTMF_COMMAND_2:
9758 if (plci_nl_busy(plci))
9759 {
9760 plci->internal_command = DTMF_COMMAND_2;
9761 return;
9762 }
9763 plci->dtmf_msg_number_queue[(plci->dtmf_send_requests)++] = plci->number;
9764 plci->internal_command = DTMF_COMMAND_3;
9765 dtmf_send_digits(plci, &plci->saved_msg.parms[3].info[1], plci->saved_msg.parms[3].length);
9766 return;
9767 case DTMF_COMMAND_3:
9768 if ((Rc != OK) && (Rc != OK_FC))
9769 {
9770 dbug(1, dprintf("[%06lx] %s,%d: Send DTMF digits failed %02x",
9771 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
9772 if (plci->dtmf_send_requests != 0)
9773 (plci->dtmf_send_requests)--;
9774 Info = _FACILITY_NOT_SUPPORTED;
9775 break;
9776 }
9777 return;
9778 }
9779 break;
9780 }
9781 sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
9782 "wws", Info, SELECTOR_DTMF, result);
9783}
9784
9785
9786static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg)
9787{
9788 word Info;
9789 word i, j;
9790 byte mask;
9791 API_PARSE dtmf_parms[5];
9792 byte result[40];
9793
9794 dbug(1, dprintf("[%06lx] %s,%d: dtmf_request",
9795 UnMapId(Id), (char *)(FILE_), __LINE__));
9796
9797 Info = GOOD;
9798 result[0] = 2;
9799 PUT_WORD(&result[1], DTMF_SUCCESS);
9800 if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED))
9801 {
9802 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
9803 UnMapId(Id), (char *)(FILE_), __LINE__));
9804 Info = _FACILITY_NOT_SUPPORTED;
9805 }
9806 else if (api_parse(&msg[1].info[1], msg[1].length, "w", dtmf_parms))
9807 {
9808 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
9809 UnMapId(Id), (char *)(FILE_), __LINE__));
9810 Info = _WRONG_MESSAGE_FORMAT;
9811 }
9812
9813 else if ((GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
9814 || (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_SEND_CODES))
9815 {
9816 if (!((a->requested_options_table[appl->Id - 1])
9817 & (1L << PRIVATE_DTMF_TONE)))
9818 {
9819 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9820 UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
9821 PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
9822 }
9823 else
9824 {
9825 for (i = 0; i < 32; i++)
9826 result[4 + i] = 0;
9827 if (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
9828 {
9829 for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
9830 {
9831 if (dtmf_digit_map[i].listen_mask != 0)
9832 result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
9833 }
9834 }
9835 else
9836 {
9837 for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
9838 {
9839 if (dtmf_digit_map[i].send_mask != 0)
9840 result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
9841 }
9842 }
9843 result[0] = 3 + 32;
9844 result[3] = 32;
9845 }
9846 }
9847
9848 else if (plci == NULL)
9849 {
9850 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
9851 UnMapId(Id), (char *)(FILE_), __LINE__));
9852 Info = _WRONG_IDENTIFIER;
9853 }
9854 else
9855 {
9856 if (!plci->State
9857 || !plci->NL.Id || plci->nl_remove_id)
9858 {
9859 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
9860 UnMapId(Id), (char *)(FILE_), __LINE__));
9861 Info = _WRONG_STATE;
9862 }
9863 else
9864 {
9865 plci->command = 0;
9866 plci->dtmf_cmd = GET_WORD(dtmf_parms[0].info);
9867 mask = 0x01;
9868 switch (plci->dtmf_cmd)
9869 {
9870
9871 case DTMF_LISTEN_TONE_START:
9872 case DTMF_LISTEN_TONE_STOP:
9873 mask <<= 1; /* fall through */
9874 case DTMF_LISTEN_MF_START:
9875 case DTMF_LISTEN_MF_STOP:
9876 mask <<= 1;
9877 if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1])
9878 & (1L << PRIVATE_DTMF_TONE)))
9879 {
9880 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9881 UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
9882 PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
9883 break;
9884 }
9885 /* fall through */
9886
9887 case DTMF_LISTEN_START:
9888 case DTMF_LISTEN_STOP:
9889 if (!(a->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
9890 && !(a->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
9891 {
9892 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
9893 UnMapId(Id), (char *)(FILE_), __LINE__));
9894 Info = _FACILITY_NOT_SUPPORTED;
9895 break;
9896 }
9897 if (mask & DTMF_LISTEN_ACTIVE_FLAG)
9898 {
9899 if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
9900 {
9901 plci->dtmf_rec_pulse_ms = 0;
9902 plci->dtmf_rec_pause_ms = 0;
9903 }
9904 else
9905 {
9906 plci->dtmf_rec_pulse_ms = GET_WORD(dtmf_parms[1].info);
9907 plci->dtmf_rec_pause_ms = GET_WORD(dtmf_parms[2].info);
9908 }
9909 }
9910 start_internal_command(Id, plci, dtmf_command);
9911 return (false);
9912
9913
9914 case DTMF_SEND_TONE:
9915 mask <<= 1; /* fall through */
9916 case DTMF_SEND_MF:
9917 mask <<= 1;
9918 if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1])
9919 & (1L << PRIVATE_DTMF_TONE)))
9920 {
9921 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9922 UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
9923 PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
9924 break;
9925 }
9926 /* fall through */
9927
9928 case DTMF_DIGITS_SEND:
9929 if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
9930 {
9931 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
9932 UnMapId(Id), (char *)(FILE_), __LINE__));
9933 Info = _WRONG_MESSAGE_FORMAT;
9934 break;
9935 }
9936 if (mask & DTMF_LISTEN_ACTIVE_FLAG)
9937 {
9938 plci->dtmf_send_pulse_ms = GET_WORD(dtmf_parms[1].info);
9939 plci->dtmf_send_pause_ms = GET_WORD(dtmf_parms[2].info);
9940 }
9941 i = 0;
9942 j = 0;
9943 while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES))
9944 {
9945 j = 0;
9946 while ((j < DTMF_DIGIT_MAP_ENTRIES)
9947 && ((dtmf_parms[3].info[i + 1] != dtmf_digit_map[j].character)
9948 || ((dtmf_digit_map[j].send_mask & mask) == 0)))
9949 {
9950 j++;
9951 }
9952 i++;
9953 }
9954 if (j == DTMF_DIGIT_MAP_ENTRIES)
9955 {
9956 dbug(1, dprintf("[%06lx] %s,%d: Incorrect DTMF digit %02x",
9957 UnMapId(Id), (char *)(FILE_), __LINE__, dtmf_parms[3].info[i]));
9958 PUT_WORD(&result[1], DTMF_INCORRECT_DIGIT);
9959 break;
9960 }
9961 if (plci->dtmf_send_requests >= ARRAY_SIZE(plci->dtmf_msg_number_queue))
9962 {
9963 dbug(1, dprintf("[%06lx] %s,%d: DTMF request overrun",
9964 UnMapId(Id), (char *)(FILE_), __LINE__));
9965 Info = _WRONG_STATE;
9966 break;
9967 }
9968 api_save_msg(dtmf_parms, "wwws", &plci->saved_msg);
9969 start_internal_command(Id, plci, dtmf_command);
9970 return (false);
9971
9972 default:
9973 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9974 UnMapId(Id), (char *)(FILE_), __LINE__, plci->dtmf_cmd));
9975 PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
9976 }
9977 }
9978 }
9979 sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
9980 "wws", Info, SELECTOR_DTMF, result);
9981 return (false);
9982}
9983
9984
9985static void dtmf_confirmation(dword Id, PLCI *plci)
9986{
9987 word i;
9988 byte result[4];
9989
9990 dbug(1, dprintf("[%06lx] %s,%d: dtmf_confirmation",
9991 UnMapId(Id), (char *)(FILE_), __LINE__));
9992
9993 result[0] = 2;
9994 PUT_WORD(&result[1], DTMF_SUCCESS);
9995 if (plci->dtmf_send_requests != 0)
9996 {
9997 sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->dtmf_msg_number_queue[0],
9998 "wws", GOOD, SELECTOR_DTMF, result);
9999 (plci->dtmf_send_requests)--;
10000 for (i = 0; i < plci->dtmf_send_requests; i++)
10001 plci->dtmf_msg_number_queue[i] = plci->dtmf_msg_number_queue[i + 1];
10002 }
10003}
10004
10005
10006static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length)
10007{
10008 word i, j, n;
10009
10010 dbug(1, dprintf("[%06lx] %s,%d: dtmf_indication",
10011 UnMapId(Id), (char *)(FILE_), __LINE__));
10012
10013 n = 0;
10014 for (i = 1; i < length; i++)
10015 {
10016 j = 0;
10017 while ((j < DTMF_DIGIT_MAP_ENTRIES)
10018 && ((msg[i] != dtmf_digit_map[j].code)
10019 || ((dtmf_digit_map[j].listen_mask & plci->dtmf_rec_active) == 0)))
10020 {
10021 j++;
10022 }
10023 if (j < DTMF_DIGIT_MAP_ENTRIES)
10024 {
10025
10026 if ((dtmf_digit_map[j].listen_mask & DTMF_TONE_LISTEN_ACTIVE_FLAG)
10027 && (plci->tone_last_indication_code == DTMF_SIGNAL_NO_TONE)
10028 && (dtmf_digit_map[j].character != DTMF_SIGNAL_UNIDENTIFIED_TONE))
10029 {
10030 if (n + 1 == i)
10031 {
10032 for (i = length; i > n + 1; i--)
10033 msg[i] = msg[i - 1];
10034 length++;
10035 i++;
10036 }
10037 msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE;
10038 }
10039 plci->tone_last_indication_code = dtmf_digit_map[j].character;
10040
10041 msg[++n] = dtmf_digit_map[j].character;
10042 }
10043 }
10044 if (n != 0)
10045 {
10046 msg[0] = (byte) n;
10047 sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg);
10048 }
10049}
10050
10051
10052/*------------------------------------------------------------------*/
10053/* DTMF parameters */
10054/*------------------------------------------------------------------*/
10055
10056static void dtmf_parameter_write(PLCI *plci)
10057{
10058 word i;
10059 byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2];
10060
10061 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_write",
10062 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
10063 (char *)(FILE_), __LINE__));
10064
10065 parameter_buffer[0] = plci->dtmf_parameter_length + 1;
10066 parameter_buffer[1] = DSP_CTRL_SET_DTMF_PARAMETERS;
10067 for (i = 0; i < plci->dtmf_parameter_length; i++)
10068 parameter_buffer[2 + i] = plci->dtmf_parameter_buffer[i];
10069 add_p(plci, FTY, parameter_buffer);
10070 sig_req(plci, TEL_CTRL, 0);
10071 send_req(plci);
10072}
10073
10074
10075static void dtmf_parameter_clear_config(PLCI *plci)
10076{
10077
10078 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_clear_config",
10079 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
10080 (char *)(FILE_), __LINE__));
10081
10082 plci->dtmf_parameter_length = 0;
10083}
10084
10085
10086static void dtmf_parameter_prepare_switch(dword Id, PLCI *plci)
10087{
10088
10089 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_prepare_switch",
10090 UnMapId(Id), (char *)(FILE_), __LINE__));
10091
10092}
10093
10094
10095static word dtmf_parameter_save_config(dword Id, PLCI *plci, byte Rc)
10096{
10097
10098 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d",
10099 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
10100
10101 return (GOOD);
10102}
10103
10104
10105static word dtmf_parameter_restore_config(dword Id, PLCI *plci, byte Rc)
10106{
10107 word Info;
10108
10109 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d",
10110 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
10111
10112 Info = GOOD;
10113 if ((plci->B1_facilities & B1_FACILITY_DTMFR)
10114 && (plci->dtmf_parameter_length != 0))
10115 {
10116 switch (plci->adjust_b_state)
10117 {
10118 case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
10119 plci->internal_command = plci->adjust_b_command;
10120 if (plci->sig_req)
10121 {
10122 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
10123 break;
10124 }
10125 dtmf_parameter_write(plci);
10126 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2;
10127 break;
10128 case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
10129 if ((Rc != OK) && (Rc != OK_FC))
10130 {
10131 dbug(1, dprintf("[%06lx] %s,%d: Restore DTMF parameters failed %02x",
10132 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
10133 Info = _WRONG_STATE;
10134 break;
10135 }
10136 break;
10137 }
10138 }
10139 return (Info);
10140}
10141
10142
10143/*------------------------------------------------------------------*/
10144/* Line interconnect facilities */
10145/*------------------------------------------------------------------*/
10146
10147
10148LI_CONFIG *li_config_table;
10149word li_total_channels;
10150
10151
10152/*------------------------------------------------------------------*/
10153/* translate a CHI information element to a channel number */
10154/* returns 0xff - any channel */
10155/* 0xfe - chi wrong coding */
10156/* 0xfd - D-channel */
10157/* 0x00 - no channel */
10158/* else channel number / PRI: timeslot */
10159/* if channels is provided we accept more than one channel. */
10160/*------------------------------------------------------------------*/
10161
10162static byte chi_to_channel(byte *chi, dword *pchannelmap)
10163{
10164 int p;
10165 int i;
10166 dword map;
10167 byte excl;
10168 byte ofs;
10169 byte ch;
10170
10171 if (pchannelmap) *pchannelmap = 0;
10172 if (!chi[0]) return 0xff;
10173 excl = 0;
10174
10175 if (chi[1] & 0x20) {
10176 if (chi[0] == 1 && chi[1] == 0xac) return 0xfd; /* exclusive d-channel */
10177 for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++);
10178 if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
10179 if ((chi[1] | 0xc8) != 0xe9) return 0xfe;
10180 if (chi[1] & 0x08) excl = 0x40;
10181
10182 /* int. id present */
10183 if (chi[1] & 0x40) {
10184 p = i + 1;
10185 for (i = p; i < chi[0] && !(chi[i] & 0x80); i++);
10186 if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
10187 }
10188
10189 /* coding standard, Number/Map, Channel Type */
10190 p = i + 1;
10191 for (i = p; i < chi[0] && !(chi[i] & 0x80); i++);
10192 if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
10193 if ((chi[p] | 0xd0) != 0xd3) return 0xfe;
10194
10195 /* Number/Map */
10196 if (chi[p] & 0x10) {
10197
10198 /* map */
10199 if ((chi[0] - p) == 4) ofs = 0;
10200 else if ((chi[0] - p) == 3) ofs = 1;
10201 else return 0xfe;
10202 ch = 0;
10203 map = 0;
10204 for (i = 0; i < 4 && p < chi[0]; i++) {
10205 p++;
10206 ch += 8;
10207 map <<= 8;
10208 if (chi[p]) {
10209 for (ch = 0; !(chi[p] & (1 << ch)); ch++);
10210 map |= chi[p];
10211 }
10212 }
10213 ch += ofs;
10214 map <<= ofs;
10215 }
10216 else {
10217
10218 /* number */
10219 p = i + 1;
10220 ch = chi[p] & 0x3f;
10221 if (pchannelmap) {
10222 if ((byte)(chi[0] - p) > 30) return 0xfe;
10223 map = 0;
10224 for (i = p; i <= chi[0]; i++) {
10225 if ((chi[i] & 0x7f) > 31) return 0xfe;
10226 map |= (1L << (chi[i] & 0x7f));
10227 }
10228 }
10229 else {
10230 if (p != chi[0]) return 0xfe;
10231 if (ch > 31) return 0xfe;
10232 map = (1L << ch);
10233 }
10234 if (chi[p] & 0x40) return 0xfe;
10235 }
10236 if (pchannelmap) *pchannelmap = map;
10237 else if (map != ((dword)(1L << ch))) return 0xfe;
10238 return (byte)(excl | ch);
10239 }
10240 else { /* not PRI */
10241 for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++);
10242 if (i != chi[0] || !(chi[i] & 0x80)) return 0xfe;
10243 if (chi[1] & 0x08) excl = 0x40;
10244
10245 switch (chi[1] | 0x98) {
10246 case 0x98: return 0;
10247 case 0x99:
10248 if (pchannelmap) *pchannelmap = 2;
10249 return excl | 1;
10250 case 0x9a:
10251 if (pchannelmap) *pchannelmap = 4;
10252 return excl | 2;
10253 case 0x9b: return 0xff;
10254 case 0x9c: return 0xfd; /* d-ch */
10255 default: return 0xfe;
10256 }
10257 }
10258}
10259
10260
10261static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id)
10262{
10263 DIVA_CAPI_ADAPTER *a;
10264 PLCI *splci;
10265 byte old_id;
10266
10267 a = plci->adapter;
10268 old_id = plci->li_bchannel_id;
10269 if (a->li_pri)
10270 {
10271 if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
10272 li_config_table[a->li_base + (old_id - 1)].plci = NULL;
10273 plci->li_bchannel_id = (bchannel_id & 0x1f) + 1;
10274 if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
10275 li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
10276 }
10277 else
10278 {
10279 if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2))
10280 {
10281 if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
10282 li_config_table[a->li_base + (old_id - 1)].plci = NULL;
10283 plci->li_bchannel_id = bchannel_id & 0x03;
10284 if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
10285 {
10286 splci = a->AdvSignalPLCI;
10287 if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
10288 {
10289 if ((splci->li_bchannel_id != 0)
10290 && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
10291 {
10292 li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
10293 }
10294 splci->li_bchannel_id = 3 - plci->li_bchannel_id;
10295 li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
10296 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d",
10297 (dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)),
10298 (char *)(FILE_), __LINE__, splci->li_bchannel_id));
10299 }
10300 }
10301 if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
10302 li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
10303 }
10304 }
10305 if ((old_id == 0) && (plci->li_bchannel_id != 0)
10306 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
10307 {
10308 mixer_clear_config(plci);
10309 }
10310 dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d",
10311 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
10312 (char *)(FILE_), __LINE__, bchannel_id, plci->li_bchannel_id));
10313}
10314
10315
10316static void mixer_set_bchannel_id(PLCI *plci, byte *chi)
10317{
10318 DIVA_CAPI_ADAPTER *a;
10319 PLCI *splci;
10320 byte ch, old_id;
10321
10322 a = plci->adapter;
10323 old_id = plci->li_bchannel_id;
10324 ch = chi_to_channel(chi, NULL);
10325 if (!(ch & 0x80))
10326 {
10327 if (a->li_pri)
10328 {
10329 if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
10330 li_config_table[a->li_base + (old_id - 1)].plci = NULL;
10331 plci->li_bchannel_id = (ch & 0x1f) + 1;
10332 if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
10333 li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
10334 }
10335 else
10336 {
10337 if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2))
10338 {
10339 if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
10340 li_config_table[a->li_base + (old_id - 1)].plci = NULL;
10341 plci->li_bchannel_id = ch & 0x1f;
10342 if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
10343 {
10344 splci = a->AdvSignalPLCI;
10345 if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
10346 {
10347 if ((splci->li_bchannel_id != 0)
10348 && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
10349 {
10350 li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
10351 }
10352 splci->li_bchannel_id = 3 - plci->li_bchannel_id;
10353 li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
10354 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
10355 (dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)),
10356 (char *)(FILE_), __LINE__, splci->li_bchannel_id));
10357 }
10358 }
10359 if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
10360 li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
10361 }
10362 }
10363 }
10364 if ((old_id == 0) && (plci->li_bchannel_id != 0)
10365 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
10366 {
10367 mixer_clear_config(plci);
10368 }
10369 dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d",
10370 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
10371 (char *)(FILE_), __LINE__, ch, plci->li_bchannel_id));
10372}
10373
10374
10375#define MIXER_MAX_DUMP_CHANNELS 34
10376
10377static void mixer_calculate_coefs(DIVA_CAPI_ADAPTER *a)
10378{
10379 word n, i, j;
10380 char *p;
10381 char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4];
10382
10383 dbug(1, dprintf("[%06lx] %s,%d: mixer_calculate_coefs",
10384 (dword)(UnMapController(a->Id)), (char *)(FILE_), __LINE__));
10385
10386 for (i = 0; i < li_total_channels; i++)
10387 {
10388 li_config_table[i].channel &= LI_CHANNEL_ADDRESSES_SET;
10389 if (li_config_table[i].chflags != 0)
10390 li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
10391 else
10392 {
10393 for (j = 0; j < li_total_channels; j++)
10394 {
10395 if (((li_config_table[i].flag_table[j]) != 0)
10396 || ((li_config_table[j].flag_table[i]) != 0))
10397 {
10398 li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
10399 }
10400 if (((li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) != 0)
10401 || ((li_config_table[j].flag_table[i] & LI_FLAG_CONFERENCE) != 0))
10402 {
10403 li_config_table[i].channel |= LI_CHANNEL_CONFERENCE;
10404 }
10405 }
10406 }
10407 }
10408 for (i = 0; i < li_total_channels; i++)
10409 {
10410 for (j = 0; j < li_total_channels; j++)
10411 {
10412 li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC);
10413 if (li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE)
10414 li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
10415 }
10416 }
10417 for (n = 0; n < li_total_channels; n++)
10418 {
10419 if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE)
10420 {
10421 for (i = 0; i < li_total_channels; i++)
10422 {
10423 if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE)
10424 {
10425 for (j = 0; j < li_total_channels; j++)
10426 {
10427 li_config_table[i].coef_table[j] |=
10428 li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j];
10429 }
10430 }
10431 }
10432 }
10433 }
10434 for (i = 0; i < li_total_channels; i++)
10435 {
10436 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
10437 {
10438 li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH;
10439 for (j = 0; j < li_total_channels; j++)
10440 {
10441 if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH)
10442 li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE;
10443 }
10444 if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE)
10445 li_config_table[i].coef_table[i] |= LI_COEF_CH_CH;
10446 }
10447 }
10448 for (i = 0; i < li_total_channels; i++)
10449 {
10450 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
10451 {
10452 for (j = 0; j < li_total_channels; j++)
10453 {
10454 if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
10455 li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
10456 if (li_config_table[i].flag_table[j] & LI_FLAG_MONITOR)
10457 li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
10458 if (li_config_table[i].flag_table[j] & LI_FLAG_MIX)
10459 li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
10460 if (li_config_table[i].flag_table[j] & LI_FLAG_PCCONNECT)
10461 li_config_table[i].coef_table[j] |= LI_COEF_PC_PC;
10462 }
10463 if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
10464 {
10465 for (j = 0; j < li_total_channels; j++)
10466 {
10467 if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
10468 {
10469 li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
10470 if (li_config_table[j].chflags & LI_CHFLAG_MIX)
10471 li_config_table[i].coef_table[j] |= LI_COEF_PC_CH | LI_COEF_PC_PC;
10472 }
10473 }
10474 }
10475 if (li_config_table[i].chflags & LI_CHFLAG_MIX)
10476 {
10477 for (j = 0; j < li_total_channels; j++)
10478 {
10479 if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)
10480 li_config_table[j].coef_table[i] |= LI_COEF_PC_CH;
10481 }
10482 }
10483 if (li_config_table[i].chflags & LI_CHFLAG_LOOP)
10484 {
10485 for (j = 0; j < li_total_channels; j++)
10486 {
10487 if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
10488 {
10489 for (n = 0; n < li_total_channels; n++)
10490 {
10491 if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT)
10492 {
10493 li_config_table[n].coef_table[j] |= LI_COEF_CH_CH;
10494 if (li_config_table[j].chflags & LI_CHFLAG_MIX)
10495 {
10496 li_config_table[n].coef_table[j] |= LI_COEF_PC_CH;
10497 if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
10498 li_config_table[n].coef_table[j] |= LI_COEF_CH_PC | LI_COEF_PC_PC;
10499 }
10500 else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
10501 li_config_table[n].coef_table[j] |= LI_COEF_CH_PC;
10502 }
10503 }
10504 }
10505 }
10506 }
10507 }
10508 }
10509 for (i = 0; i < li_total_channels; i++)
10510 {
10511 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
10512 {
10513 if (li_config_table[i].chflags & (LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP))
10514 li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
10515 if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
10516 li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
10517 if (li_config_table[i].chflags & LI_CHFLAG_MIX)
10518 li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
10519 for (j = 0; j < li_total_channels; j++)
10520 {
10521 if ((li_config_table[i].flag_table[j] &
10522 (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_MONITOR))
10523 || (li_config_table[j].flag_table[i] &
10524 (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX)))
10525 {
10526 li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
10527 }
10528 if (li_config_table[i].flag_table[j] & (LI_FLAG_PCCONNECT | LI_FLAG_MONITOR))
10529 li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
10530 if (li_config_table[j].flag_table[i] & (LI_FLAG_PCCONNECT | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX))
10531 li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
10532 }
10533 if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE))
10534 {
10535 li_config_table[i].coef_table[i] |= LI_COEF_PC_CH | LI_COEF_CH_PC;
10536 li_config_table[i].channel |= LI_CHANNEL_TX_DATA | LI_CHANNEL_RX_DATA;
10537 }
10538 }
10539 }
10540 for (i = 0; i < li_total_channels; i++)
10541 {
10542 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
10543 {
10544 j = 0;
10545 while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT))
10546 j++;
10547 if (j < li_total_channels)
10548 {
10549 for (j = 0; j < li_total_channels; j++)
10550 {
10551 li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_PC_CH);
10552 if (li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT)
10553 li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
10554 }
10555 }
10556 }
10557 }
10558 n = li_total_channels;
10559 if (n > MIXER_MAX_DUMP_CHANNELS)
10560 n = MIXER_MAX_DUMP_CHANNELS;
10561
10562 p = hex_line;
10563 for (j = 0; j < n; j++)
10564 {
10565 if ((j & 0x7) == 0)
10566 *(p++) = ' ';
10567 p = hex_byte_pack(p, li_config_table[j].curchnl);
10568 }
10569 *p = '\0';
10570 dbug(1, dprintf("[%06lx] CURRENT %s",
10571 (dword)(UnMapController(a->Id)), (char *)hex_line));
10572 p = hex_line;
10573 for (j = 0; j < n; j++)
10574 {
10575 if ((j & 0x7) == 0)
10576 *(p++) = ' ';
10577 p = hex_byte_pack(p, li_config_table[j].channel);
10578 }
10579 *p = '\0';
10580 dbug(1, dprintf("[%06lx] CHANNEL %s",
10581 (dword)(UnMapController(a->Id)), (char *)hex_line));
10582 p = hex_line;
10583 for (j = 0; j < n; j++)
10584 {
10585 if ((j & 0x7) == 0)
10586 *(p++) = ' ';
10587 p = hex_byte_pack(p, li_config_table[j].chflags);
10588 }
10589 *p = '\0';
10590 dbug(1, dprintf("[%06lx] CHFLAG %s",
10591 (dword)(UnMapController(a->Id)), (char *)hex_line));
10592 for (i = 0; i < n; i++)
10593 {
10594 p = hex_line;
10595 for (j = 0; j < n; j++)
10596 {
10597 if ((j & 0x7) == 0)
10598 *(p++) = ' ';
10599 p = hex_byte_pack(p, li_config_table[i].flag_table[j]);
10600 }
10601 *p = '\0';
10602 dbug(1, dprintf("[%06lx] FLAG[%02x]%s",
10603 (dword)(UnMapController(a->Id)), i, (char *)hex_line));
10604 }
10605 for (i = 0; i < n; i++)
10606 {
10607 p = hex_line;
10608 for (j = 0; j < n; j++)
10609 {
10610 if ((j & 0x7) == 0)
10611 *(p++) = ' ';
10612 p = hex_byte_pack(p, li_config_table[i].coef_table[j]);
10613 }
10614 *p = '\0';
10615 dbug(1, dprintf("[%06lx] COEF[%02x]%s",
10616 (dword)(UnMapController(a->Id)), i, (char *)hex_line));
10617 }
10618}
10619
10620
10621static struct
10622{
10623 byte mask;
10624 byte line_flags;
10625} mixer_write_prog_pri[] =
10626{
10627 { LI_COEF_CH_CH, 0 },
10628 { LI_COEF_CH_PC, MIXER_COEF_LINE_TO_PC_FLAG },
10629 { LI_COEF_PC_CH, MIXER_COEF_LINE_FROM_PC_FLAG },
10630 { LI_COEF_PC_PC, MIXER_COEF_LINE_TO_PC_FLAG | MIXER_COEF_LINE_FROM_PC_FLAG }
10631};
10632
10633static struct
10634{
10635 byte from_ch;
10636 byte to_ch;
10637 byte mask;
10638 byte xconnect_override;
10639} mixer_write_prog_bri[] =
10640{
10641 { 0, 0, LI_COEF_CH_CH, 0x01 }, /* B to B */
10642 { 1, 0, LI_COEF_CH_CH, 0x01 }, /* Alt B to B */
10643 { 0, 0, LI_COEF_PC_CH, 0x80 }, /* PC to B */
10644 { 1, 0, LI_COEF_PC_CH, 0x01 }, /* Alt PC to B */
10645 { 2, 0, LI_COEF_CH_CH, 0x00 }, /* IC to B */
10646 { 3, 0, LI_COEF_CH_CH, 0x00 }, /* Alt IC to B */
10647 { 0, 0, LI_COEF_CH_PC, 0x80 }, /* B to PC */
10648 { 1, 0, LI_COEF_CH_PC, 0x01 }, /* Alt B to PC */
10649 { 0, 0, LI_COEF_PC_PC, 0x01 }, /* PC to PC */
10650 { 1, 0, LI_COEF_PC_PC, 0x01 }, /* Alt PC to PC */
10651 { 2, 0, LI_COEF_CH_PC, 0x00 }, /* IC to PC */
10652 { 3, 0, LI_COEF_CH_PC, 0x00 }, /* Alt IC to PC */
10653 { 0, 2, LI_COEF_CH_CH, 0x00 }, /* B to IC */
10654 { 1, 2, LI_COEF_CH_CH, 0x00 }, /* Alt B to IC */
10655 { 0, 2, LI_COEF_PC_CH, 0x00 }, /* PC to IC */
10656 { 1, 2, LI_COEF_PC_CH, 0x00 }, /* Alt PC to IC */
10657 { 2, 2, LI_COEF_CH_CH, 0x00 }, /* IC to IC */
10658 { 3, 2, LI_COEF_CH_CH, 0x00 }, /* Alt IC to IC */
10659 { 1, 1, LI_COEF_CH_CH, 0x01 }, /* Alt B to Alt B */
10660 { 0, 1, LI_COEF_CH_CH, 0x01 }, /* B to Alt B */
10661 { 1, 1, LI_COEF_PC_CH, 0x80 }, /* Alt PC to Alt B */
10662 { 0, 1, LI_COEF_PC_CH, 0x01 }, /* PC to Alt B */
10663 { 3, 1, LI_COEF_CH_CH, 0x00 }, /* Alt IC to Alt B */
10664 { 2, 1, LI_COEF_CH_CH, 0x00 }, /* IC to Alt B */
10665 { 1, 1, LI_COEF_CH_PC, 0x80 }, /* Alt B to Alt PC */
10666 { 0, 1, LI_COEF_CH_PC, 0x01 }, /* B to Alt PC */
10667 { 1, 1, LI_COEF_PC_PC, 0x01 }, /* Alt PC to Alt PC */
10668 { 0, 1, LI_COEF_PC_PC, 0x01 }, /* PC to Alt PC */
10669 { 3, 1, LI_COEF_CH_PC, 0x00 }, /* Alt IC to Alt PC */
10670 { 2, 1, LI_COEF_CH_PC, 0x00 }, /* IC to Alt PC */
10671 { 1, 3, LI_COEF_CH_CH, 0x00 }, /* Alt B to Alt IC */
10672 { 0, 3, LI_COEF_CH_CH, 0x00 }, /* B to Alt IC */
10673 { 1, 3, LI_COEF_PC_CH, 0x00 }, /* Alt PC to Alt IC */
10674 { 0, 3, LI_COEF_PC_CH, 0x00 }, /* PC to Alt IC */
10675 { 3, 3, LI_COEF_CH_CH, 0x00 }, /* Alt IC to Alt IC */
10676 { 2, 3, LI_COEF_CH_CH, 0x00 } /* IC to Alt IC */
10677};
10678
10679static byte mixer_swapped_index_bri[] =
10680{
10681 18, /* B to B */
10682 19, /* Alt B to B */
10683 20, /* PC to B */
10684 21, /* Alt PC to B */
10685 22, /* IC to B */
10686 23, /* Alt IC to B */
10687 24, /* B to PC */
10688 25, /* Alt B to PC */
10689 26, /* PC to PC */
10690 27, /* Alt PC to PC */
10691 28, /* IC to PC */
10692 29, /* Alt IC to PC */
10693 30, /* B to IC */
10694 31, /* Alt B to IC */
10695 32, /* PC to IC */
10696 33, /* Alt PC to IC */
10697 34, /* IC to IC */
10698 35, /* Alt IC to IC */
10699 0, /* Alt B to Alt B */
10700 1, /* B to Alt B */
10701 2, /* Alt PC to Alt B */
10702 3, /* PC to Alt B */
10703 4, /* Alt IC to Alt B */
10704 5, /* IC to Alt B */
10705 6, /* Alt B to Alt PC */
10706 7, /* B to Alt PC */
10707 8, /* Alt PC to Alt PC */
10708 9, /* PC to Alt PC */
10709 10, /* Alt IC to Alt PC */
10710 11, /* IC to Alt PC */
10711 12, /* Alt B to Alt IC */
10712 13, /* B to Alt IC */
10713 14, /* Alt PC to Alt IC */
10714 15, /* PC to Alt IC */
10715 16, /* Alt IC to Alt IC */
10716 17 /* IC to Alt IC */
10717};
10718
10719static struct
10720{
10721 byte mask;
10722 byte from_pc;
10723 byte to_pc;
10724} xconnect_write_prog[] =
10725{
10726 { LI_COEF_CH_CH, false, false },
10727 { LI_COEF_CH_PC, false, true },
10728 { LI_COEF_PC_CH, true, false },
10729 { LI_COEF_PC_PC, true, true }
10730};
10731
10732
10733static void xconnect_query_addresses(PLCI *plci)
10734{
10735 DIVA_CAPI_ADAPTER *a;
10736 word w, ch;
10737 byte *p;
10738
10739 dbug(1, dprintf("[%06lx] %s,%d: xconnect_query_addresses",
10740 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
10741 (char *)(FILE_), __LINE__));
10742
10743 a = plci->adapter;
10744 if (a->li_pri && ((plci->li_bchannel_id == 0)
10745 || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)))
10746 {
10747 dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
10748 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
10749 (char *)(FILE_), __LINE__));
10750 return;
10751 }
10752 p = plci->internal_req_buffer;
10753 ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
10754 *(p++) = UDATA_REQUEST_XCONNECT_FROM;
10755 w = ch;
10756 *(p++) = (byte) w;
10757 *(p++) = (byte)(w >> 8);
10758 w = ch | XCONNECT_CHANNEL_PORT_PC;
10759 *(p++) = (byte) w;
10760 *(p++) = (byte)(w >> 8);
10761 plci->NData[0].P = plci->internal_req_buffer;
10762 plci->NData[0].PLength = p - plci->internal_req_buffer;
10763 plci->NL.X = plci->NData;
10764 plci->NL.ReqCh = 0;
10765 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
10766 plci->adapter->request(&plci->NL);
10767}
10768
10769
10770static void xconnect_write_coefs(PLCI *plci, word internal_command)
10771{
10772
10773 dbug(1, dprintf("[%06lx] %s,%d: xconnect_write_coefs %04x",
10774 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
10775 (char *)(FILE_), __LINE__, internal_command));
10776
10777 plci->li_write_command = internal_command;
10778 plci->li_write_channel = 0;
10779}
10780
10781
10782static byte xconnect_write_coefs_process(dword Id, PLCI *plci, byte Rc)
10783{
10784 DIVA_CAPI_ADAPTER *a;
10785 word w, n, i, j, r, s, to_ch;
10786 dword d;
10787 byte *p;
10788 struct xconnect_transfer_address_s *transfer_address;
10789 byte ch_map[MIXER_CHANNELS_BRI];
10790
10791 dbug(1, dprintf("[%06x] %s,%d: xconnect_write_coefs_process %02x %d",
10792 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->li_write_channel));
10793
10794 a = plci->adapter;
10795 if ((plci->li_bchannel_id == 0)
10796 || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
10797 {
10798 dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
10799 UnMapId(Id), (char *)(FILE_), __LINE__));
10800 return (true);
10801 }
10802 i = a->li_base + (plci->li_bchannel_id - 1);
10803 j = plci->li_write_channel;
10804 p = plci->internal_req_buffer;
10805 if (j != 0)
10806 {
10807 if ((Rc != OK) && (Rc != OK_FC))
10808 {
10809 dbug(1, dprintf("[%06lx] %s,%d: LI write coefs failed %02x",
10810 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
10811 return (false);
10812 }
10813 }
10814 if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
10815 {
10816 r = 0;
10817 s = 0;
10818 if (j < li_total_channels)
10819 {
10820 if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET)
10821 {
10822 s = ((li_config_table[i].send_b.card_address.low | li_config_table[i].send_b.card_address.high) ?
10823 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_PC | LI_COEF_PC_PC)) &
10824 ((li_config_table[i].send_pc.card_address.low | li_config_table[i].send_pc.card_address.high) ?
10825 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_PC_CH));
10826 }
10827 r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
10828 while ((j < li_total_channels)
10829 && ((r == 0)
10830 || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
10831 || (!li_config_table[j].adapter->li_pri
10832 && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
10833 || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
10834 || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
10835 && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
10836 || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
10837 || ((li_config_table[j].adapter->li_base != a->li_base)
10838 && !(r & s &
10839 ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
10840 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
10841 ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
10842 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))))
10843 {
10844 j++;
10845 if (j < li_total_channels)
10846 r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
10847 }
10848 }
10849 if (j < li_total_channels)
10850 {
10851 plci->internal_command = plci->li_write_command;
10852 if (plci_nl_busy(plci))
10853 return (true);
10854 to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
10855 *(p++) = UDATA_REQUEST_XCONNECT_TO;
10856 do
10857 {
10858 if (li_config_table[j].adapter->li_base != a->li_base)
10859 {
10860 r &= s &
10861 ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
10862 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
10863 ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
10864 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC));
10865 }
10866 n = 0;
10867 do
10868 {
10869 if (r & xconnect_write_prog[n].mask)
10870 {
10871 if (xconnect_write_prog[n].from_pc)
10872 transfer_address = &(li_config_table[j].send_pc);
10873 else
10874 transfer_address = &(li_config_table[j].send_b);
10875 d = transfer_address->card_address.low;
10876 *(p++) = (byte) d;
10877 *(p++) = (byte)(d >> 8);
10878 *(p++) = (byte)(d >> 16);
10879 *(p++) = (byte)(d >> 24);
10880 d = transfer_address->card_address.high;
10881 *(p++) = (byte) d;
10882 *(p++) = (byte)(d >> 8);
10883 *(p++) = (byte)(d >> 16);
10884 *(p++) = (byte)(d >> 24);
10885 d = transfer_address->offset;
10886 *(p++) = (byte) d;
10887 *(p++) = (byte)(d >> 8);
10888 *(p++) = (byte)(d >> 16);
10889 *(p++) = (byte)(d >> 24);
10890 w = xconnect_write_prog[n].to_pc ? to_ch | XCONNECT_CHANNEL_PORT_PC : to_ch;
10891 *(p++) = (byte) w;
10892 *(p++) = (byte)(w >> 8);
10893 w = ((li_config_table[i].coef_table[j] & xconnect_write_prog[n].mask) == 0) ? 0x01 :
10894 (li_config_table[i].adapter->u_law ?
10895 (li_config_table[j].adapter->u_law ? 0x80 : 0x86) :
10896 (li_config_table[j].adapter->u_law ? 0x7a : 0x80));
10897 *(p++) = (byte) w;
10898 *(p++) = (byte) 0;
10899 li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4;
10900 }
10901 n++;
10902 } while ((n < ARRAY_SIZE(xconnect_write_prog))
10903 && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
10904 if (n == ARRAY_SIZE(xconnect_write_prog))
10905 {
10906 do
10907 {
10908 j++;
10909 if (j < li_total_channels)
10910 r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
10911 } while ((j < li_total_channels)
10912 && ((r == 0)
10913 || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
10914 || (!li_config_table[j].adapter->li_pri
10915 && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
10916 || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
10917 || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
10918 && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
10919 || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
10920 || ((li_config_table[j].adapter->li_base != a->li_base)
10921 && !(r & s &
10922 ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
10923 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
10924 ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
10925 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))));
10926 }
10927 } while ((j < li_total_channels)
10928 && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
10929 }
10930 else if (j == li_total_channels)
10931 {
10932 plci->internal_command = plci->li_write_command;
10933 if (plci_nl_busy(plci))
10934 return (true);
10935 if (a->li_pri)
10936 {
10937 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
10938 w = 0;
10939 if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
10940 w |= MIXER_FEATURE_ENABLE_TX_DATA;
10941 if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
10942 w |= MIXER_FEATURE_ENABLE_RX_DATA;
10943 *(p++) = (byte) w;
10944 *(p++) = (byte)(w >> 8);
10945 }
10946 else
10947 {
10948 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
10949 w = 0;
10950 if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
10951 && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
10952 {
10953 w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
10954 }
10955 if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
10956 w |= MIXER_FEATURE_ENABLE_TX_DATA;
10957 if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
10958 w |= MIXER_FEATURE_ENABLE_RX_DATA;
10959 *(p++) = (byte) w;
10960 *(p++) = (byte)(w >> 8);
10961 for (j = 0; j < sizeof(ch_map); j += 2)
10962 {
10963 if (plci->li_bchannel_id == 2)
10964 {
10965 ch_map[j] = (byte)(j + 1);
10966 ch_map[j + 1] = (byte) j;
10967 }
10968 else
10969 {
10970 ch_map[j] = (byte) j;
10971 ch_map[j + 1] = (byte)(j + 1);
10972 }
10973 }
10974 for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
10975 {
10976 i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
10977 j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
10978 if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
10979 {
10980 *p = (mixer_write_prog_bri[n].xconnect_override != 0) ?
10981 mixer_write_prog_bri[n].xconnect_override :
10982 ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
10983 if ((i >= a->li_base + MIXER_BCHANNELS_BRI) || (j >= a->li_base + MIXER_BCHANNELS_BRI))
10984 {
10985 w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
10986 li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
10987 }
10988 }
10989 else
10990 {
10991 *p = 0x00;
10992 if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
10993 {
10994 w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
10995 if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
10996 *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
10997 }
10998 }
10999 p++;
11000 }
11001 }
11002 j = li_total_channels + 1;
11003 }
11004 }
11005 else
11006 {
11007 if (j <= li_total_channels)
11008 {
11009 plci->internal_command = plci->li_write_command;
11010 if (plci_nl_busy(plci))
11011 return (true);
11012 if (j < a->li_base)
11013 j = a->li_base;
11014 if (a->li_pri)
11015 {
11016 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
11017 w = 0;
11018 if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
11019 w |= MIXER_FEATURE_ENABLE_TX_DATA;
11020 if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
11021 w |= MIXER_FEATURE_ENABLE_RX_DATA;
11022 *(p++) = (byte) w;
11023 *(p++) = (byte)(w >> 8);
11024 for (n = 0; n < ARRAY_SIZE(mixer_write_prog_pri); n++)
11025 {
11026 *(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags);
11027 for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
11028 {
11029 w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
11030 if (w & mixer_write_prog_pri[n].mask)
11031 {
11032 *(p++) = (li_config_table[i].coef_table[j] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
11033 li_config_table[i].coef_table[j] ^= mixer_write_prog_pri[n].mask << 4;
11034 }
11035 else
11036 *(p++) = 0x00;
11037 }
11038 *(p++) = (byte)((plci->li_bchannel_id - 1) | MIXER_COEF_LINE_ROW_FLAG | mixer_write_prog_pri[n].line_flags);
11039 for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
11040 {
11041 w = ((li_config_table[j].coef_table[i] & 0xf) ^ (li_config_table[j].coef_table[i] >> 4));
11042 if (w & mixer_write_prog_pri[n].mask)
11043 {
11044 *(p++) = (li_config_table[j].coef_table[i] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
11045 li_config_table[j].coef_table[i] ^= mixer_write_prog_pri[n].mask << 4;
11046 }
11047 else
11048 *(p++) = 0x00;
11049 }
11050 }
11051 }
11052 else
11053 {
11054 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
11055 w = 0;
11056 if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
11057 && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
11058 {
11059 w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
11060 }
11061 if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
11062 w |= MIXER_FEATURE_ENABLE_TX_DATA;
11063 if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
11064 w |= MIXER_FEATURE_ENABLE_RX_DATA;
11065 *(p++) = (byte) w;
11066 *(p++) = (byte)(w >> 8);
11067 for (j = 0; j < sizeof(ch_map); j += 2)
11068 {
11069 if (plci->li_bchannel_id == 2)
11070 {
11071 ch_map[j] = (byte)(j + 1);
11072 ch_map[j + 1] = (byte) j;
11073 }
11074 else
11075 {
11076 ch_map[j] = (byte) j;
11077 ch_map[j + 1] = (byte)(j + 1);
11078 }
11079 }
11080 for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
11081 {
11082 i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
11083 j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
11084 if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
11085 {
11086 *p = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
11087 w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
11088 li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
11089 }
11090 else
11091 {
11092 *p = 0x00;
11093 if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
11094 {
11095 w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
11096 if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
11097 *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
11098 }
11099 }
11100 p++;
11101 }
11102 }
11103 j = li_total_channels + 1;
11104 }
11105 }
11106 plci->li_write_channel = j;
11107 if (p != plci->internal_req_buffer)
11108 {
11109 plci->NData[0].P = plci->internal_req_buffer;
11110 plci->NData[0].PLength = p - plci->internal_req_buffer;
11111 plci->NL.X = plci->NData;
11112 plci->NL.ReqCh = 0;
11113 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
11114 plci->adapter->request(&plci->NL);
11115 }
11116 return (true);
11117}
11118
11119
11120static void mixer_notify_update(PLCI *plci, byte others)
11121{
11122 DIVA_CAPI_ADAPTER *a;
11123 word i, w;
11124 PLCI *notify_plci;
11125 byte msg[sizeof(CAPI_MSG_HEADER) + 6];
11126
11127 dbug(1, dprintf("[%06lx] %s,%d: mixer_notify_update %d",
11128 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
11129 (char *)(FILE_), __LINE__, others));
11130
11131 a = plci->adapter;
11132 if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
11133 {
11134 if (others)
11135 plci->li_notify_update = true;
11136 i = 0;
11137 do
11138 {
11139 notify_plci = NULL;
11140 if (others)
11141 {
11142 while ((i < li_total_channels) && (li_config_table[i].plci == NULL))
11143 i++;
11144 if (i < li_total_channels)
11145 notify_plci = li_config_table[i++].plci;
11146 }
11147 else
11148 {
11149 if ((plci->li_bchannel_id != 0)
11150 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
11151 {
11152 notify_plci = plci;
11153 }
11154 }
11155 if ((notify_plci != NULL)
11156 && !notify_plci->li_notify_update
11157 && (notify_plci->appl != NULL)
11158 && (notify_plci->State)
11159 && notify_plci->NL.Id && !notify_plci->nl_remove_id)
11160 {
11161 notify_plci->li_notify_update = true;
11162 ((CAPI_MSG *) msg)->header.length = 18;
11163 ((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id;
11164 ((CAPI_MSG *) msg)->header.command = _FACILITY_R;
11165 ((CAPI_MSG *) msg)->header.number = 0;
11166 ((CAPI_MSG *) msg)->header.controller = notify_plci->adapter->Id;
11167 ((CAPI_MSG *) msg)->header.plci = notify_plci->Id;
11168 ((CAPI_MSG *) msg)->header.ncci = 0;
11169 ((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT;
11170 ((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3;
11171 ((CAPI_MSG *) msg)->info.facility_req.structs[1] = LI_REQ_SILENT_UPDATE & 0xff;
11172 ((CAPI_MSG *) msg)->info.facility_req.structs[2] = LI_REQ_SILENT_UPDATE >> 8;
11173 ((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0;
11174 w = api_put(notify_plci->appl, (CAPI_MSG *) msg);
11175 if (w != _QUEUE_FULL)
11176 {
11177 if (w != 0)
11178 {
11179 dbug(1, dprintf("[%06lx] %s,%d: Interconnect notify failed %06x %d",
11180 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
11181 (char *)(FILE_), __LINE__,
11182 (dword)((notify_plci->Id << 8) | UnMapController(notify_plci->adapter->Id)), w));
11183 }
11184 notify_plci->li_notify_update = false;
11185 }
11186 }
11187 } while (others && (notify_plci != NULL));
11188 if (others)
11189 plci->li_notify_update = false;
11190 }
11191}
11192
11193
11194static void mixer_clear_config(PLCI *plci)
11195{
11196 DIVA_CAPI_ADAPTER *a;
11197 word i, j;
11198
11199 dbug(1, dprintf("[%06lx] %s,%d: mixer_clear_config",
11200 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
11201 (char *)(FILE_), __LINE__));
11202
11203 plci->li_notify_update = false;
11204 plci->li_plci_b_write_pos = 0;
11205 plci->li_plci_b_read_pos = 0;
11206 plci->li_plci_b_req_pos = 0;
11207 a = plci->adapter;
11208 if ((plci->li_bchannel_id != 0)
11209 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
11210 {
11211 i = a->li_base + (plci->li_bchannel_id - 1);
11212 li_config_table[i].curchnl = 0;
11213 li_config_table[i].channel = 0;
11214 li_config_table[i].chflags = 0;
11215 for (j = 0; j < li_total_channels; j++)
11216 {
11217 li_config_table[j].flag_table[i] = 0;
11218 li_config_table[i].flag_table[j] = 0;
11219 li_config_table[i].coef_table[j] = 0;
11220 li_config_table[j].coef_table[i] = 0;
11221 }
11222 if (!a->li_pri)
11223 {
11224 li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
11225 if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
11226 {
11227 i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
11228 li_config_table[i].curchnl = 0;
11229 li_config_table[i].channel = 0;
11230 li_config_table[i].chflags = 0;
11231 for (j = 0; j < li_total_channels; j++)
11232 {
11233 li_config_table[i].flag_table[j] = 0;
11234 li_config_table[j].flag_table[i] = 0;
11235 li_config_table[i].coef_table[j] = 0;
11236 li_config_table[j].coef_table[i] = 0;
11237 }
11238 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
11239 {
11240 i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
11241 li_config_table[i].curchnl = 0;
11242 li_config_table[i].channel = 0;
11243 li_config_table[i].chflags = 0;
11244 for (j = 0; j < li_total_channels; j++)
11245 {
11246 li_config_table[i].flag_table[j] = 0;
11247 li_config_table[j].flag_table[i] = 0;
11248 li_config_table[i].coef_table[j] = 0;
11249 li_config_table[j].coef_table[i] = 0;
11250 }
11251 }
11252 }
11253 }
11254 }
11255}
11256
11257
11258static void mixer_prepare_switch(dword Id, PLCI *plci)
11259{
11260
11261 dbug(1, dprintf("[%06lx] %s,%d: mixer_prepare_switch",
11262 UnMapId(Id), (char *)(FILE_), __LINE__));
11263
11264 do
11265 {
11266 mixer_indication_coefs_set(Id, plci);
11267 } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
11268}
11269
11270
11271static word mixer_save_config(dword Id, PLCI *plci, byte Rc)
11272{
11273 DIVA_CAPI_ADAPTER *a;
11274 word i, j;
11275
11276 dbug(1, dprintf("[%06lx] %s,%d: mixer_save_config %02x %d",
11277 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
11278
11279 a = plci->adapter;
11280 if ((plci->li_bchannel_id != 0)
11281 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
11282 {
11283 i = a->li_base + (plci->li_bchannel_id - 1);
11284 for (j = 0; j < li_total_channels; j++)
11285 {
11286 li_config_table[i].coef_table[j] &= 0xf;
11287 li_config_table[j].coef_table[i] &= 0xf;
11288 }
11289 if (!a->li_pri)
11290 li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
11291 }
11292 return (GOOD);
11293}
11294
11295
11296static word mixer_restore_config(dword Id, PLCI *plci, byte Rc)
11297{
11298 DIVA_CAPI_ADAPTER *a;
11299 word Info;
11300
11301 dbug(1, dprintf("[%06lx] %s,%d: mixer_restore_config %02x %d",
11302 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
11303
11304 Info = GOOD;
11305 a = plci->adapter;
11306 if ((plci->B1_facilities & B1_FACILITY_MIXER)
11307 && (plci->li_bchannel_id != 0)
11308 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
11309 {
11310 switch (plci->adjust_b_state)
11311 {
11312 case ADJUST_B_RESTORE_MIXER_1:
11313 if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11314 {
11315 plci->internal_command = plci->adjust_b_command;
11316 if (plci_nl_busy(plci))
11317 {
11318 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
11319 break;
11320 }
11321 xconnect_query_addresses(plci);
11322 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2;
11323 break;
11324 }
11325 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
11326 Rc = OK;
11327 /* fall through */
11328 case ADJUST_B_RESTORE_MIXER_2:
11329 case ADJUST_B_RESTORE_MIXER_3:
11330 case ADJUST_B_RESTORE_MIXER_4:
11331 if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
11332 {
11333 dbug(1, dprintf("[%06lx] %s,%d: Adjust B query addresses failed %02x",
11334 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
11335 Info = _WRONG_STATE;
11336 break;
11337 }
11338 if (Rc == OK)
11339 {
11340 if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
11341 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_3;
11342 else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)
11343 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
11344 }
11345 else if (Rc == 0)
11346 {
11347 if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
11348 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_4;
11349 else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
11350 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
11351 }
11352 if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5)
11353 {
11354 plci->internal_command = plci->adjust_b_command;
11355 break;
11356 }
11357 /* fall through */
11358 case ADJUST_B_RESTORE_MIXER_5:
11359 xconnect_write_coefs(plci, plci->adjust_b_command);
11360 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6;
11361 Rc = OK;
11362 /* fall through */
11363 case ADJUST_B_RESTORE_MIXER_6:
11364 if (!xconnect_write_coefs_process(Id, plci, Rc))
11365 {
11366 dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
11367 UnMapId(Id), (char *)(FILE_), __LINE__));
11368 Info = _FACILITY_NOT_SUPPORTED;
11369 break;
11370 }
11371 if (plci->internal_command)
11372 break;
11373 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7;
11374 case ADJUST_B_RESTORE_MIXER_7:
11375 break;
11376 }
11377 }
11378 return (Info);
11379}
11380
11381
11382static void mixer_command(dword Id, PLCI *plci, byte Rc)
11383{
11384 DIVA_CAPI_ADAPTER *a;
11385 word i, internal_command;
11386
11387 dbug(1, dprintf("[%06lx] %s,%d: mixer_command %02x %04x %04x",
11388 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
11389 plci->li_cmd));
11390
11391 a = plci->adapter;
11392 internal_command = plci->internal_command;
11393 plci->internal_command = 0;
11394 switch (plci->li_cmd)
11395 {
11396 case LI_REQ_CONNECT:
11397 case LI_REQ_DISCONNECT:
11398 case LI_REQ_SILENT_UPDATE:
11399 switch (internal_command)
11400 {
11401 default:
11402 if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
11403 {
11404 adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
11405 B1_FACILITY_MIXER), MIXER_COMMAND_1);
11406 }
11407 /* fall through */
11408 case MIXER_COMMAND_1:
11409 if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
11410 {
11411 if (adjust_b_process(Id, plci, Rc) != GOOD)
11412 {
11413 dbug(1, dprintf("[%06lx] %s,%d: Load mixer failed",
11414 UnMapId(Id), (char *)(FILE_), __LINE__));
11415 break;
11416 }
11417 if (plci->internal_command)
11418 return;
11419 }
11420 plci->li_plci_b_req_pos = plci->li_plci_b_write_pos;
11421 if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
11422 || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER)
11423 && (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities &
11424 ~B1_FACILITY_MIXER)) == plci->B1_resource)))
11425 {
11426 xconnect_write_coefs(plci, MIXER_COMMAND_2);
11427 }
11428 else
11429 {
11430 do
11431 {
11432 mixer_indication_coefs_set(Id, plci);
11433 } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
11434 }
11435 /* fall through */
11436 case MIXER_COMMAND_2:
11437 if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
11438 || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER)
11439 && (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities &
11440 ~B1_FACILITY_MIXER)) == plci->B1_resource)))
11441 {
11442 if (!xconnect_write_coefs_process(Id, plci, Rc))
11443 {
11444 dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
11445 UnMapId(Id), (char *)(FILE_), __LINE__));
11446 if (plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
11447 {
11448 do
11449 {
11450 plci->li_plci_b_write_pos = (plci->li_plci_b_write_pos == 0) ?
11451 LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1;
11452 i = (plci->li_plci_b_write_pos == 0) ?
11453 LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1;
11454 } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
11455 && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
11456 }
11457 break;
11458 }
11459 if (plci->internal_command)
11460 return;
11461 }
11462 if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
11463 {
11464 adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
11465 ~B1_FACILITY_MIXER), MIXER_COMMAND_3);
11466 }
11467 /* fall through */
11468 case MIXER_COMMAND_3:
11469 if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
11470 {
11471 if (adjust_b_process(Id, plci, Rc) != GOOD)
11472 {
11473 dbug(1, dprintf("[%06lx] %s,%d: Unload mixer failed",
11474 UnMapId(Id), (char *)(FILE_), __LINE__));
11475 break;
11476 }
11477 if (plci->internal_command)
11478 return;
11479 }
11480 break;
11481 }
11482 break;
11483 }
11484 if ((plci->li_bchannel_id == 0)
11485 || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
11486 {
11487 dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out %d",
11488 UnMapId(Id), (char *)(FILE_), __LINE__, (int)(plci->li_bchannel_id)));
11489 }
11490 else
11491 {
11492 i = a->li_base + (plci->li_bchannel_id - 1);
11493 li_config_table[i].curchnl = plci->li_channel_bits;
11494 if (!a->li_pri && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
11495 {
11496 i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
11497 li_config_table[i].curchnl = plci->li_channel_bits;
11498 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
11499 {
11500 i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
11501 li_config_table[i].curchnl = plci->li_channel_bits;
11502 }
11503 }
11504 }
11505}
11506
11507
11508static void li_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
11509 dword plci_b_id, byte connect, dword li_flags)
11510{
11511 word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
11512 PLCI *plci_b;
11513 DIVA_CAPI_ADAPTER *a_b;
11514
11515 a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]);
11516 plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
11517 ch_a = a->li_base + (plci->li_bchannel_id - 1);
11518 if (!a->li_pri && (plci->tel == ADV_VOICE)
11519 && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
11520 {
11521 ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
11522 ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
11523 a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
11524 }
11525 else
11526 {
11527 ch_a_v = ch_a;
11528 ch_a_s = ch_a;
11529 }
11530 ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
11531 if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
11532 && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
11533 {
11534 ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
11535 ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
11536 a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
11537 }
11538 else
11539 {
11540 ch_b_v = ch_b;
11541 ch_b_s = ch_b;
11542 }
11543 if (connect)
11544 {
11545 li_config_table[ch_a].flag_table[ch_a_v] &= ~LI_FLAG_MONITOR;
11546 li_config_table[ch_a].flag_table[ch_a_s] &= ~LI_FLAG_MONITOR;
11547 li_config_table[ch_a_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
11548 li_config_table[ch_a_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
11549 }
11550 li_config_table[ch_a].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
11551 li_config_table[ch_a].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
11552 li_config_table[ch_b_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
11553 li_config_table[ch_b_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
11554 if (ch_a_v == ch_b_v)
11555 {
11556 li_config_table[ch_a_v].flag_table[ch_b_v] &= ~LI_FLAG_CONFERENCE;
11557 li_config_table[ch_a_s].flag_table[ch_b_s] &= ~LI_FLAG_CONFERENCE;
11558 }
11559 else
11560 {
11561 if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
11562 {
11563 for (i = 0; i < li_total_channels; i++)
11564 {
11565 if (i != ch_a_v)
11566 li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE;
11567 }
11568 }
11569 if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
11570 {
11571 for (i = 0; i < li_total_channels; i++)
11572 {
11573 if (i != ch_a_s)
11574 li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE;
11575 }
11576 }
11577 if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE)
11578 {
11579 for (i = 0; i < li_total_channels; i++)
11580 {
11581 if (i != ch_a_v)
11582 li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE;
11583 }
11584 }
11585 if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE)
11586 {
11587 for (i = 0; i < li_total_channels; i++)
11588 {
11589 if (i != ch_a_s)
11590 li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE;
11591 }
11592 }
11593 }
11594 if (li_flags & LI_FLAG_CONFERENCE_A_B)
11595 {
11596 li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
11597 li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
11598 li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
11599 li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
11600 }
11601 if (li_flags & LI_FLAG_CONFERENCE_B_A)
11602 {
11603 li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
11604 li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
11605 li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
11606 li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
11607 }
11608 if (li_flags & LI_FLAG_MONITOR_A)
11609 {
11610 li_config_table[ch_a].flag_table[ch_a_v] |= LI_FLAG_MONITOR;
11611 li_config_table[ch_a].flag_table[ch_a_s] |= LI_FLAG_MONITOR;
11612 }
11613 if (li_flags & LI_FLAG_MONITOR_B)
11614 {
11615 li_config_table[ch_a].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
11616 li_config_table[ch_a].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
11617 }
11618 if (li_flags & LI_FLAG_ANNOUNCEMENT_A)
11619 {
11620 li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
11621 li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
11622 }
11623 if (li_flags & LI_FLAG_ANNOUNCEMENT_B)
11624 {
11625 li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
11626 li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
11627 }
11628 if (li_flags & LI_FLAG_MIX_A)
11629 {
11630 li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_MIX;
11631 li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_MIX;
11632 }
11633 if (li_flags & LI_FLAG_MIX_B)
11634 {
11635 li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_MIX;
11636 li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_MIX;
11637 }
11638 if (ch_a_v != ch_a_s)
11639 {
11640 li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
11641 li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
11642 }
11643 if (ch_b_v != ch_b_s)
11644 {
11645 li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
11646 li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
11647 }
11648}
11649
11650
11651static void li2_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
11652 dword plci_b_id, byte connect, dword li_flags)
11653{
11654 word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
11655 PLCI *plci_b;
11656 DIVA_CAPI_ADAPTER *a_b;
11657
11658 a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]);
11659 plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
11660 ch_a = a->li_base + (plci->li_bchannel_id - 1);
11661 if (!a->li_pri && (plci->tel == ADV_VOICE)
11662 && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
11663 {
11664 ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
11665 ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
11666 a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
11667 }
11668 else
11669 {
11670 ch_a_v = ch_a;
11671 ch_a_s = ch_a;
11672 }
11673 ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
11674 if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
11675 && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
11676 {
11677 ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
11678 ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
11679 a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
11680 }
11681 else
11682 {
11683 ch_b_v = ch_b;
11684 ch_b_s = ch_b;
11685 }
11686 if (connect)
11687 {
11688 li_config_table[ch_b].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
11689 li_config_table[ch_b].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
11690 li_config_table[ch_b_v].flag_table[ch_b] &= ~LI_FLAG_MIX;
11691 li_config_table[ch_b_s].flag_table[ch_b] &= ~LI_FLAG_MIX;
11692 li_config_table[ch_b].flag_table[ch_b] &= ~LI_FLAG_PCCONNECT;
11693 li_config_table[ch_b].chflags &= ~(LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP);
11694 }
11695 li_config_table[ch_b_v].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11696 li_config_table[ch_b_s].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11697 li_config_table[ch_b_v].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11698 li_config_table[ch_b_s].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11699 li_config_table[ch_a_v].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11700 li_config_table[ch_a_v].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11701 li_config_table[ch_a_s].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11702 li_config_table[ch_a_s].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
11703 if (li_flags & LI2_FLAG_INTERCONNECT_A_B)
11704 {
11705 li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
11706 li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
11707 li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
11708 li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
11709 }
11710 if (li_flags & LI2_FLAG_INTERCONNECT_B_A)
11711 {
11712 li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
11713 li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
11714 li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
11715 li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
11716 }
11717 if (li_flags & LI2_FLAG_MONITOR_B)
11718 {
11719 li_config_table[ch_b].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
11720 li_config_table[ch_b].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
11721 }
11722 if (li_flags & LI2_FLAG_MIX_B)
11723 {
11724 li_config_table[ch_b_v].flag_table[ch_b] |= LI_FLAG_MIX;
11725 li_config_table[ch_b_s].flag_table[ch_b] |= LI_FLAG_MIX;
11726 }
11727 if (li_flags & LI2_FLAG_MONITOR_X)
11728 li_config_table[ch_b].chflags |= LI_CHFLAG_MONITOR;
11729 if (li_flags & LI2_FLAG_MIX_X)
11730 li_config_table[ch_b].chflags |= LI_CHFLAG_MIX;
11731 if (li_flags & LI2_FLAG_LOOP_B)
11732 {
11733 li_config_table[ch_b_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
11734 li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
11735 li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
11736 li_config_table[ch_b_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
11737 }
11738 if (li_flags & LI2_FLAG_LOOP_PC)
11739 li_config_table[ch_b].flag_table[ch_b] |= LI_FLAG_PCCONNECT;
11740 if (li_flags & LI2_FLAG_LOOP_X)
11741 li_config_table[ch_b].chflags |= LI_CHFLAG_LOOP;
11742 if (li_flags & LI2_FLAG_PCCONNECT_A_B)
11743 li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_PCCONNECT;
11744 if (li_flags & LI2_FLAG_PCCONNECT_B_A)
11745 li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_PCCONNECT;
11746 if (ch_a_v != ch_a_s)
11747 {
11748 li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
11749 li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
11750 }
11751 if (ch_b_v != ch_b_s)
11752 {
11753 li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
11754 li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
11755 }
11756}
11757
11758
11759static word li_check_main_plci(dword Id, PLCI *plci)
11760{
11761 if (plci == NULL)
11762 {
11763 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
11764 UnMapId(Id), (char *)(FILE_), __LINE__));
11765 return (_WRONG_IDENTIFIER);
11766 }
11767 if (!plci->State
11768 || !plci->NL.Id || plci->nl_remove_id
11769 || (plci->li_bchannel_id == 0))
11770 {
11771 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
11772 UnMapId(Id), (char *)(FILE_), __LINE__));
11773 return (_WRONG_STATE);
11774 }
11775 li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci;
11776 return (GOOD);
11777}
11778
11779
11780static PLCI *li_check_plci_b(dword Id, PLCI *plci,
11781 dword plci_b_id, word plci_b_write_pos, byte *p_result)
11782{
11783 byte ctlr_b;
11784 PLCI *plci_b;
11785
11786 if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
11787 LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
11788 {
11789 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
11790 UnMapId(Id), (char *)(FILE_), __LINE__));
11791 PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
11792 return (NULL);
11793 }
11794 ctlr_b = 0;
11795 if ((plci_b_id & 0x7f) != 0)
11796 {
11797 ctlr_b = MapController((byte)(plci_b_id & 0x7f));
11798 if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
11799 ctlr_b = 0;
11800 }
11801 if ((ctlr_b == 0)
11802 || (((plci_b_id >> 8) & 0xff) == 0)
11803 || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
11804 {
11805 dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
11806 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
11807 PUT_WORD(p_result, _WRONG_IDENTIFIER);
11808 return (NULL);
11809 }
11810 plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
11811 if (!plci_b->State
11812 || !plci_b->NL.Id || plci_b->nl_remove_id
11813 || (plci_b->li_bchannel_id == 0))
11814 {
11815 dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
11816 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
11817 PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
11818 return (NULL);
11819 }
11820 li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci = plci_b;
11821 if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
11822 ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER))
11823 && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11824 || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
11825 {
11826 dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
11827 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
11828 PUT_WORD(p_result, _WRONG_IDENTIFIER);
11829 return (NULL);
11830 }
11831 if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource,
11832 (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
11833 {
11834 dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
11835 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource));
11836 PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
11837 return (NULL);
11838 }
11839 return (plci_b);
11840}
11841
11842
11843static PLCI *li2_check_plci_b(dword Id, PLCI *plci,
11844 dword plci_b_id, word plci_b_write_pos, byte *p_result)
11845{
11846 byte ctlr_b;
11847 PLCI *plci_b;
11848
11849 if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
11850 LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
11851 {
11852 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
11853 UnMapId(Id), (char *)(FILE_), __LINE__));
11854 PUT_WORD(p_result, _WRONG_STATE);
11855 return (NULL);
11856 }
11857 ctlr_b = 0;
11858 if ((plci_b_id & 0x7f) != 0)
11859 {
11860 ctlr_b = MapController((byte)(plci_b_id & 0x7f));
11861 if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
11862 ctlr_b = 0;
11863 }
11864 if ((ctlr_b == 0)
11865 || (((plci_b_id >> 8) & 0xff) == 0)
11866 || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
11867 {
11868 dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
11869 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
11870 PUT_WORD(p_result, _WRONG_IDENTIFIER);
11871 return (NULL);
11872 }
11873 plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
11874 if (!plci_b->State
11875 || !plci_b->NL.Id || plci_b->nl_remove_id
11876 || (plci_b->li_bchannel_id == 0)
11877 || (li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci != plci_b))
11878 {
11879 dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
11880 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
11881 PUT_WORD(p_result, _WRONG_STATE);
11882 return (NULL);
11883 }
11884 if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
11885 ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER))
11886 && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11887 || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
11888 {
11889 dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
11890 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
11891 PUT_WORD(p_result, _WRONG_IDENTIFIER);
11892 return (NULL);
11893 }
11894 if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource,
11895 (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
11896 {
11897 dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
11898 UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource));
11899 PUT_WORD(p_result, _WRONG_STATE);
11900 return (NULL);
11901 }
11902 return (plci_b);
11903}
11904
11905
11906static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg)
11907{
11908 word Info;
11909 word i;
11910 dword d, li_flags, plci_b_id;
11911 PLCI *plci_b;
11912 API_PARSE li_parms[3];
11913 API_PARSE li_req_parms[3];
11914 API_PARSE li_participant_struct[2];
11915 API_PARSE li_participant_parms[3];
11916 word participant_parms_pos;
11917 byte result_buffer[32];
11918 byte *result;
11919 word result_pos;
11920 word plci_b_write_pos;
11921
11922 dbug(1, dprintf("[%06lx] %s,%d: mixer_request",
11923 UnMapId(Id), (char *)(FILE_), __LINE__));
11924
11925 Info = GOOD;
11926 result = result_buffer;
11927 result_buffer[0] = 0;
11928 if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED))
11929 {
11930 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
11931 UnMapId(Id), (char *)(FILE_), __LINE__));
11932 Info = _FACILITY_NOT_SUPPORTED;
11933 }
11934 else if (api_parse(&msg[1].info[1], msg[1].length, "ws", li_parms))
11935 {
11936 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
11937 UnMapId(Id), (char *)(FILE_), __LINE__));
11938 Info = _WRONG_MESSAGE_FORMAT;
11939 }
11940 else
11941 {
11942 result_buffer[0] = 3;
11943 PUT_WORD(&result_buffer[1], GET_WORD(li_parms[0].info));
11944 result_buffer[3] = 0;
11945 switch (GET_WORD(li_parms[0].info))
11946 {
11947 case LI_GET_SUPPORTED_SERVICES:
11948 if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
11949 {
11950 result_buffer[0] = 17;
11951 result_buffer[3] = 14;
11952 PUT_WORD(&result_buffer[4], GOOD);
11953 d = 0;
11954 if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_CH)
11955 d |= LI_CONFERENCING_SUPPORTED;
11956 if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
11957 d |= LI_MONITORING_SUPPORTED;
11958 if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
11959 d |= LI_ANNOUNCEMENTS_SUPPORTED | LI_MIXING_SUPPORTED;
11960 if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11961 d |= LI_CROSS_CONTROLLER_SUPPORTED;
11962 PUT_DWORD(&result_buffer[6], d);
11963 if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11964 {
11965 d = 0;
11966 for (i = 0; i < li_total_channels; i++)
11967 {
11968 if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11969 && (li_config_table[i].adapter->li_pri
11970 || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
11971 {
11972 d++;
11973 }
11974 }
11975 }
11976 else
11977 {
11978 d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
11979 }
11980 PUT_DWORD(&result_buffer[10], d / 2);
11981 PUT_DWORD(&result_buffer[14], d);
11982 }
11983 else
11984 {
11985 result_buffer[0] = 25;
11986 result_buffer[3] = 22;
11987 PUT_WORD(&result_buffer[4], GOOD);
11988 d = LI2_ASYMMETRIC_SUPPORTED | LI2_B_LOOPING_SUPPORTED | LI2_X_LOOPING_SUPPORTED;
11989 if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
11990 d |= LI2_MONITORING_SUPPORTED | LI2_REMOTE_MONITORING_SUPPORTED;
11991 if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
11992 d |= LI2_MIXING_SUPPORTED | LI2_REMOTE_MIXING_SUPPORTED;
11993 if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_PC)
11994 d |= LI2_PC_LOOPING_SUPPORTED;
11995 if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11996 d |= LI2_CROSS_CONTROLLER_SUPPORTED;
11997 PUT_DWORD(&result_buffer[6], d);
11998 d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
11999 PUT_DWORD(&result_buffer[10], d / 2);
12000 PUT_DWORD(&result_buffer[14], d - 1);
12001 if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
12002 {
12003 d = 0;
12004 for (i = 0; i < li_total_channels; i++)
12005 {
12006 if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
12007 && (li_config_table[i].adapter->li_pri
12008 || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
12009 {
12010 d++;
12011 }
12012 }
12013 }
12014 PUT_DWORD(&result_buffer[18], d / 2);
12015 PUT_DWORD(&result_buffer[22], d - 1);
12016 }
12017 break;
12018
12019 case LI_REQ_CONNECT:
12020 if (li_parms[1].length == 8)
12021 {
12022 appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
12023 if (api_parse(&li_parms[1].info[1], li_parms[1].length, "dd", li_req_parms))
12024 {
12025 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12026 UnMapId(Id), (char *)(FILE_), __LINE__));
12027 Info = _WRONG_MESSAGE_FORMAT;
12028 break;
12029 }
12030 plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff;
12031 li_flags = GET_DWORD(li_req_parms[1].info);
12032 Info = li_check_main_plci(Id, plci);
12033 result_buffer[0] = 9;
12034 result_buffer[3] = 6;
12035 PUT_DWORD(&result_buffer[4], plci_b_id);
12036 PUT_WORD(&result_buffer[8], GOOD);
12037 if (Info != GOOD)
12038 break;
12039 result = plci->saved_msg.info;
12040 for (i = 0; i <= result_buffer[0]; i++)
12041 result[i] = result_buffer[i];
12042 plci_b_write_pos = plci->li_plci_b_write_pos;
12043 plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
12044 if (plci_b == NULL)
12045 break;
12046 li_update_connect(Id, a, plci, plci_b_id, true, li_flags);
12047 plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG;
12048 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12049 plci->li_plci_b_write_pos = plci_b_write_pos;
12050 }
12051 else
12052 {
12053 appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
12054 if (api_parse(&li_parms[1].info[1], li_parms[1].length, "ds", li_req_parms))
12055 {
12056 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12057 UnMapId(Id), (char *)(FILE_), __LINE__));
12058 Info = _WRONG_MESSAGE_FORMAT;
12059 break;
12060 }
12061 li_flags = GET_DWORD(li_req_parms[0].info) & ~(LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A);
12062 Info = li_check_main_plci(Id, plci);
12063 result_buffer[0] = 7;
12064 result_buffer[3] = 4;
12065 PUT_WORD(&result_buffer[4], Info);
12066 result_buffer[6] = 0;
12067 if (Info != GOOD)
12068 break;
12069 result = plci->saved_msg.info;
12070 for (i = 0; i <= result_buffer[0]; i++)
12071 result[i] = result_buffer[i];
12072 plci_b_write_pos = plci->li_plci_b_write_pos;
12073 participant_parms_pos = 0;
12074 result_pos = 7;
12075 li2_update_connect(Id, a, plci, UnMapId(Id), true, li_flags);
12076 while (participant_parms_pos < li_req_parms[1].length)
12077 {
12078 result[result_pos] = 6;
12079 result_pos += 7;
12080 PUT_DWORD(&result[result_pos - 6], 0);
12081 PUT_WORD(&result[result_pos - 2], GOOD);
12082 if (api_parse(&li_req_parms[1].info[1 + participant_parms_pos],
12083 (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
12084 {
12085 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12086 UnMapId(Id), (char *)(FILE_), __LINE__));
12087 PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
12088 break;
12089 }
12090 if (api_parse(&li_participant_struct[0].info[1],
12091 li_participant_struct[0].length, "dd", li_participant_parms))
12092 {
12093 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12094 UnMapId(Id), (char *)(FILE_), __LINE__));
12095 PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
12096 break;
12097 }
12098 plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff;
12099 li_flags = GET_DWORD(li_participant_parms[1].info);
12100 PUT_DWORD(&result[result_pos - 6], plci_b_id);
12101 if (sizeof(result) - result_pos < 7)
12102 {
12103 dbug(1, dprintf("[%06lx] %s,%d: LI result overrun",
12104 UnMapId(Id), (char *)(FILE_), __LINE__));
12105 PUT_WORD(&result[result_pos - 2], _WRONG_STATE);
12106 break;
12107 }
12108 plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
12109 if (plci_b != NULL)
12110 {
12111 li2_update_connect(Id, a, plci, plci_b_id, true, li_flags);
12112 plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id |
12113 ((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A |
12114 LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG);
12115 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12116 }
12117 participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
12118 (&li_req_parms[1].info[1]));
12119 }
12120 result[0] = (byte)(result_pos - 1);
12121 result[3] = (byte)(result_pos - 4);
12122 result[6] = (byte)(result_pos - 7);
12123 i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
12124 if ((plci_b_write_pos == plci->li_plci_b_read_pos)
12125 || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
12126 {
12127 plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
12128 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12129 }
12130 else
12131 plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
12132 plci->li_plci_b_write_pos = plci_b_write_pos;
12133 }
12134 mixer_calculate_coefs(a);
12135 plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
12136 mixer_notify_update(plci, true);
12137 sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
12138 "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
12139 plci->command = 0;
12140 plci->li_cmd = GET_WORD(li_parms[0].info);
12141 start_internal_command(Id, plci, mixer_command);
12142 return (false);
12143
12144 case LI_REQ_DISCONNECT:
12145 if (li_parms[1].length == 4)
12146 {
12147 appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
12148 if (api_parse(&li_parms[1].info[1], li_parms[1].length, "d", li_req_parms))
12149 {
12150 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12151 UnMapId(Id), (char *)(FILE_), __LINE__));
12152 Info = _WRONG_MESSAGE_FORMAT;
12153 break;
12154 }
12155 plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff;
12156 Info = li_check_main_plci(Id, plci);
12157 result_buffer[0] = 9;
12158 result_buffer[3] = 6;
12159 PUT_DWORD(&result_buffer[4], GET_DWORD(li_req_parms[0].info));
12160 PUT_WORD(&result_buffer[8], GOOD);
12161 if (Info != GOOD)
12162 break;
12163 result = plci->saved_msg.info;
12164 for (i = 0; i <= result_buffer[0]; i++)
12165 result[i] = result_buffer[i];
12166 plci_b_write_pos = plci->li_plci_b_write_pos;
12167 plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
12168 if (plci_b == NULL)
12169 break;
12170 li_update_connect(Id, a, plci, plci_b_id, false, 0);
12171 plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG;
12172 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12173 plci->li_plci_b_write_pos = plci_b_write_pos;
12174 }
12175 else
12176 {
12177 appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
12178 if (api_parse(&li_parms[1].info[1], li_parms[1].length, "s", li_req_parms))
12179 {
12180 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12181 UnMapId(Id), (char *)(FILE_), __LINE__));
12182 Info = _WRONG_MESSAGE_FORMAT;
12183 break;
12184 }
12185 Info = li_check_main_plci(Id, plci);
12186 result_buffer[0] = 7;
12187 result_buffer[3] = 4;
12188 PUT_WORD(&result_buffer[4], Info);
12189 result_buffer[6] = 0;
12190 if (Info != GOOD)
12191 break;
12192 result = plci->saved_msg.info;
12193 for (i = 0; i <= result_buffer[0]; i++)
12194 result[i] = result_buffer[i];
12195 plci_b_write_pos = plci->li_plci_b_write_pos;
12196 participant_parms_pos = 0;
12197 result_pos = 7;
12198 while (participant_parms_pos < li_req_parms[0].length)
12199 {
12200 result[result_pos] = 6;
12201 result_pos += 7;
12202 PUT_DWORD(&result[result_pos - 6], 0);
12203 PUT_WORD(&result[result_pos - 2], GOOD);
12204 if (api_parse(&li_req_parms[0].info[1 + participant_parms_pos],
12205 (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
12206 {
12207 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12208 UnMapId(Id), (char *)(FILE_), __LINE__));
12209 PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
12210 break;
12211 }
12212 if (api_parse(&li_participant_struct[0].info[1],
12213 li_participant_struct[0].length, "d", li_participant_parms))
12214 {
12215 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12216 UnMapId(Id), (char *)(FILE_), __LINE__));
12217 PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
12218 break;
12219 }
12220 plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff;
12221 PUT_DWORD(&result[result_pos - 6], plci_b_id);
12222 if (sizeof(result) - result_pos < 7)
12223 {
12224 dbug(1, dprintf("[%06lx] %s,%d: LI result overrun",
12225 UnMapId(Id), (char *)(FILE_), __LINE__));
12226 PUT_WORD(&result[result_pos - 2], _WRONG_STATE);
12227 break;
12228 }
12229 plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
12230 if (plci_b != NULL)
12231 {
12232 li2_update_connect(Id, a, plci, plci_b_id, false, 0);
12233 plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
12234 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12235 }
12236 participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
12237 (&li_req_parms[0].info[1]));
12238 }
12239 result[0] = (byte)(result_pos - 1);
12240 result[3] = (byte)(result_pos - 4);
12241 result[6] = (byte)(result_pos - 7);
12242 i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
12243 if ((plci_b_write_pos == plci->li_plci_b_read_pos)
12244 || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
12245 {
12246 plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
12247 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12248 }
12249 else
12250 plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
12251 plci->li_plci_b_write_pos = plci_b_write_pos;
12252 }
12253 mixer_calculate_coefs(a);
12254 plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
12255 mixer_notify_update(plci, true);
12256 sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
12257 "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
12258 plci->command = 0;
12259 plci->li_cmd = GET_WORD(li_parms[0].info);
12260 start_internal_command(Id, plci, mixer_command);
12261 return (false);
12262
12263 case LI_REQ_SILENT_UPDATE:
12264 if (!plci || !plci->State
12265 || !plci->NL.Id || plci->nl_remove_id
12266 || (plci->li_bchannel_id == 0)
12267 || (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci != plci))
12268 {
12269 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
12270 UnMapId(Id), (char *)(FILE_), __LINE__));
12271 return (false);
12272 }
12273 plci_b_write_pos = plci->li_plci_b_write_pos;
12274 if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
12275 LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
12276 {
12277 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
12278 UnMapId(Id), (char *)(FILE_), __LINE__));
12279 return (false);
12280 }
12281 i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
12282 if ((plci_b_write_pos == plci->li_plci_b_read_pos)
12283 || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
12284 {
12285 plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
12286 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12287 }
12288 else
12289 plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
12290 plci->li_plci_b_write_pos = plci_b_write_pos;
12291 plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
12292 plci->command = 0;
12293 plci->li_cmd = GET_WORD(li_parms[0].info);
12294 start_internal_command(Id, plci, mixer_command);
12295 return (false);
12296
12297 default:
12298 dbug(1, dprintf("[%06lx] %s,%d: LI unknown request %04x",
12299 UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(li_parms[0].info)));
12300 Info = _FACILITY_NOT_SUPPORTED;
12301 }
12302 }
12303 sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
12304 "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
12305 return (false);
12306}
12307
12308
12309static void mixer_indication_coefs_set(dword Id, PLCI *plci)
12310{
12311 dword d;
12312 byte result[12];
12313
12314 dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_coefs_set",
12315 UnMapId(Id), (char *)(FILE_), __LINE__));
12316
12317 if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
12318 {
12319 do
12320 {
12321 d = plci->li_plci_b_queue[plci->li_plci_b_read_pos];
12322 if (!(d & LI_PLCI_B_SKIP_FLAG))
12323 {
12324 if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
12325 {
12326 if (d & LI_PLCI_B_DISC_FLAG)
12327 {
12328 result[0] = 5;
12329 PUT_WORD(&result[1], LI_IND_DISCONNECT);
12330 result[3] = 2;
12331 PUT_WORD(&result[4], _LI_USER_INITIATED);
12332 }
12333 else
12334 {
12335 result[0] = 7;
12336 PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE);
12337 result[3] = 4;
12338 PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
12339 }
12340 }
12341 else
12342 {
12343 if (d & LI_PLCI_B_DISC_FLAG)
12344 {
12345 result[0] = 9;
12346 PUT_WORD(&result[1], LI_IND_DISCONNECT);
12347 result[3] = 6;
12348 PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
12349 PUT_WORD(&result[8], _LI_USER_INITIATED);
12350 }
12351 else
12352 {
12353 result[0] = 7;
12354 PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE);
12355 result[3] = 4;
12356 PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
12357 }
12358 }
12359 sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,
12360 "ws", SELECTOR_LINE_INTERCONNECT, result);
12361 }
12362 plci->li_plci_b_read_pos = (plci->li_plci_b_read_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ?
12363 0 : plci->li_plci_b_read_pos + 1;
12364 } while (!(d & LI_PLCI_B_LAST_FLAG) && (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos));
12365 }
12366}
12367
12368
12369static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length)
12370{
12371 word i, j, ch;
12372 struct xconnect_transfer_address_s s, *p;
12373 DIVA_CAPI_ADAPTER *a;
12374
12375 dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_from %d",
12376 UnMapId(Id), (char *)(FILE_), __LINE__, (int)length));
12377
12378 a = plci->adapter;
12379 i = 1;
12380 for (i = 1; i < length; i += 16)
12381 {
12382 s.card_address.low = msg[i] | (msg[i + 1] << 8) | (((dword)(msg[i + 2])) << 16) | (((dword)(msg[i + 3])) << 24);
12383 s.card_address.high = msg[i + 4] | (msg[i + 5] << 8) | (((dword)(msg[i + 6])) << 16) | (((dword)(msg[i + 7])) << 24);
12384 s.offset = msg[i + 8] | (msg[i + 9] << 8) | (((dword)(msg[i + 10])) << 16) | (((dword)(msg[i + 11])) << 24);
12385 ch = msg[i + 12] | (msg[i + 13] << 8);
12386 j = ch & XCONNECT_CHANNEL_NUMBER_MASK;
12387 if (!a->li_pri && (plci->li_bchannel_id == 2))
12388 j = 1 - j;
12389 j += a->li_base;
12390 if (ch & XCONNECT_CHANNEL_PORT_PC)
12391 p = &(li_config_table[j].send_pc);
12392 else
12393 p = &(li_config_table[j].send_b);
12394 p->card_address.low = s.card_address.low;
12395 p->card_address.high = s.card_address.high;
12396 p->offset = s.offset;
12397 li_config_table[j].channel |= LI_CHANNEL_ADDRESSES_SET;
12398 }
12399 if (plci->internal_command_queue[0]
12400 && ((plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
12401 || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
12402 || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)))
12403 {
12404 (*(plci->internal_command_queue[0]))(Id, plci, 0);
12405 if (!plci->internal_command)
12406 next_internal_command(Id, plci);
12407 }
12408 mixer_notify_update(plci, true);
12409}
12410
12411
12412static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length)
12413{
12414
12415 dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_to %d",
12416 UnMapId(Id), (char *)(FILE_), __LINE__, (int) length));
12417
12418}
12419
12420
12421static byte mixer_notify_source_removed(PLCI *plci, dword plci_b_id)
12422{
12423 word plci_b_write_pos;
12424
12425 plci_b_write_pos = plci->li_plci_b_write_pos;
12426 if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
12427 LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 1)
12428 {
12429 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
12430 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
12431 (char *)(FILE_), __LINE__));
12432 return (false);
12433 }
12434 plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
12435 plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
12436 plci->li_plci_b_write_pos = plci_b_write_pos;
12437 return (true);
12438}
12439
12440
12441static void mixer_remove(PLCI *plci)
12442{
12443 DIVA_CAPI_ADAPTER *a;
12444 PLCI *notify_plci;
12445 dword plci_b_id;
12446 word i, j;
12447
12448 dbug(1, dprintf("[%06lx] %s,%d: mixer_remove",
12449 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
12450 (char *)(FILE_), __LINE__));
12451
12452 a = plci->adapter;
12453 plci_b_id = (plci->Id << 8) | UnMapController(plci->adapter->Id);
12454 if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
12455 {
12456 if ((plci->li_bchannel_id != 0)
12457 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
12458 {
12459 i = a->li_base + (plci->li_bchannel_id - 1);
12460 if ((li_config_table[i].curchnl | li_config_table[i].channel) & LI_CHANNEL_INVOLVED)
12461 {
12462 for (j = 0; j < li_total_channels; j++)
12463 {
12464 if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
12465 || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT))
12466 {
12467 notify_plci = li_config_table[j].plci;
12468 if ((notify_plci != NULL)
12469 && (notify_plci != plci)
12470 && (notify_plci->appl != NULL)
12471 && !(notify_plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
12472 && (notify_plci->State)
12473 && notify_plci->NL.Id && !notify_plci->nl_remove_id)
12474 {
12475 mixer_notify_source_removed(notify_plci, plci_b_id);
12476 }
12477 }
12478 }
12479 mixer_clear_config(plci);
12480 mixer_calculate_coefs(a);
12481 mixer_notify_update(plci, true);
12482 }
12483 li_config_table[i].plci = NULL;
12484 plci->li_bchannel_id = 0;
12485 }
12486 }
12487}
12488
12489
12490/*------------------------------------------------------------------*/
12491/* Echo canceller facilities */
12492/*------------------------------------------------------------------*/
12493
12494
12495static void ec_write_parameters(PLCI *plci)
12496{
12497 word w;
12498 byte parameter_buffer[6];
12499
12500 dbug(1, dprintf("[%06lx] %s,%d: ec_write_parameters",
12501 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
12502 (char *)(FILE_), __LINE__));
12503
12504 parameter_buffer[0] = 5;
12505 parameter_buffer[1] = DSP_CTRL_SET_LEC_PARAMETERS;
12506 PUT_WORD(&parameter_buffer[2], plci->ec_idi_options);
12507 plci->ec_idi_options &= ~LEC_RESET_COEFFICIENTS;
12508 w = (plci->ec_tail_length == 0) ? 128 : plci->ec_tail_length;
12509 PUT_WORD(&parameter_buffer[4], w);
12510 add_p(plci, FTY, parameter_buffer);
12511 sig_req(plci, TEL_CTRL, 0);
12512 send_req(plci);
12513}
12514
12515
12516static void ec_clear_config(PLCI *plci)
12517{
12518
12519 dbug(1, dprintf("[%06lx] %s,%d: ec_clear_config",
12520 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
12521 (char *)(FILE_), __LINE__));
12522
12523 plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
12524 LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING;
12525 plci->ec_tail_length = 0;
12526}
12527
12528
12529static void ec_prepare_switch(dword Id, PLCI *plci)
12530{
12531
12532 dbug(1, dprintf("[%06lx] %s,%d: ec_prepare_switch",
12533 UnMapId(Id), (char *)(FILE_), __LINE__));
12534
12535}
12536
12537
12538static word ec_save_config(dword Id, PLCI *plci, byte Rc)
12539{
12540
12541 dbug(1, dprintf("[%06lx] %s,%d: ec_save_config %02x %d",
12542 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
12543
12544 return (GOOD);
12545}
12546
12547
12548static word ec_restore_config(dword Id, PLCI *plci, byte Rc)
12549{
12550 word Info;
12551
12552 dbug(1, dprintf("[%06lx] %s,%d: ec_restore_config %02x %d",
12553 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
12554
12555 Info = GOOD;
12556 if (plci->B1_facilities & B1_FACILITY_EC)
12557 {
12558 switch (plci->adjust_b_state)
12559 {
12560 case ADJUST_B_RESTORE_EC_1:
12561 plci->internal_command = plci->adjust_b_command;
12562 if (plci->sig_req)
12563 {
12564 plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
12565 break;
12566 }
12567 ec_write_parameters(plci);
12568 plci->adjust_b_state = ADJUST_B_RESTORE_EC_2;
12569 break;
12570 case ADJUST_B_RESTORE_EC_2:
12571 if ((Rc != OK) && (Rc != OK_FC))
12572 {
12573 dbug(1, dprintf("[%06lx] %s,%d: Restore EC failed %02x",
12574 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
12575 Info = _WRONG_STATE;
12576 break;
12577 }
12578 break;
12579 }
12580 }
12581 return (Info);
12582}
12583
12584
12585static void ec_command(dword Id, PLCI *plci, byte Rc)
12586{
12587 word internal_command, Info;
12588 byte result[8];
12589
12590 dbug(1, dprintf("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d",
12591 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
12592 plci->ec_cmd, plci->ec_idi_options, plci->ec_tail_length));
12593
12594 Info = GOOD;
12595 if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
12596 {
12597 result[0] = 2;
12598 PUT_WORD(&result[1], EC_SUCCESS);
12599 }
12600 else
12601 {
12602 result[0] = 5;
12603 PUT_WORD(&result[1], plci->ec_cmd);
12604 result[3] = 2;
12605 PUT_WORD(&result[4], GOOD);
12606 }
12607 internal_command = plci->internal_command;
12608 plci->internal_command = 0;
12609 switch (plci->ec_cmd)
12610 {
12611 case EC_ENABLE_OPERATION:
12612 case EC_FREEZE_COEFFICIENTS:
12613 case EC_RESUME_COEFFICIENT_UPDATE:
12614 case EC_RESET_COEFFICIENTS:
12615 switch (internal_command)
12616 {
12617 default:
12618 adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
12619 B1_FACILITY_EC), EC_COMMAND_1);
12620 /* fall through */
12621 case EC_COMMAND_1:
12622 if (adjust_b_process(Id, plci, Rc) != GOOD)
12623 {
12624 dbug(1, dprintf("[%06lx] %s,%d: Load EC failed",
12625 UnMapId(Id), (char *)(FILE_), __LINE__));
12626 Info = _FACILITY_NOT_SUPPORTED;
12627 break;
12628 }
12629 if (plci->internal_command)
12630 return;
12631 /* fall through */
12632 case EC_COMMAND_2:
12633 if (plci->sig_req)
12634 {
12635 plci->internal_command = EC_COMMAND_2;
12636 return;
12637 }
12638 plci->internal_command = EC_COMMAND_3;
12639 ec_write_parameters(plci);
12640 return;
12641 case EC_COMMAND_3:
12642 if ((Rc != OK) && (Rc != OK_FC))
12643 {
12644 dbug(1, dprintf("[%06lx] %s,%d: Enable EC failed %02x",
12645 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
12646 Info = _FACILITY_NOT_SUPPORTED;
12647 break;
12648 }
12649 break;
12650 }
12651 break;
12652
12653 case EC_DISABLE_OPERATION:
12654 switch (internal_command)
12655 {
12656 default:
12657 case EC_COMMAND_1:
12658 if (plci->B1_facilities & B1_FACILITY_EC)
12659 {
12660 if (plci->sig_req)
12661 {
12662 plci->internal_command = EC_COMMAND_1;
12663 return;
12664 }
12665 plci->internal_command = EC_COMMAND_2;
12666 ec_write_parameters(plci);
12667 return;
12668 }
12669 Rc = OK;
12670 /* fall through */
12671 case EC_COMMAND_2:
12672 if ((Rc != OK) && (Rc != OK_FC))
12673 {
12674 dbug(1, dprintf("[%06lx] %s,%d: Disable EC failed %02x",
12675 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
12676 Info = _FACILITY_NOT_SUPPORTED;
12677 break;
12678 }
12679 adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
12680 ~B1_FACILITY_EC), EC_COMMAND_3);
12681 /* fall through */
12682 case EC_COMMAND_3:
12683 if (adjust_b_process(Id, plci, Rc) != GOOD)
12684 {
12685 dbug(1, dprintf("[%06lx] %s,%d: Unload EC failed",
12686 UnMapId(Id), (char *)(FILE_), __LINE__));
12687 Info = _FACILITY_NOT_SUPPORTED;
12688 break;
12689 }
12690 if (plci->internal_command)
12691 return;
12692 break;
12693 }
12694 break;
12695 }
12696 sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
12697 "wws", Info, (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
12698 PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
12699}
12700
12701
12702static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg)
12703{
12704 word Info;
12705 word opt;
12706 API_PARSE ec_parms[3];
12707 byte result[16];
12708
12709 dbug(1, dprintf("[%06lx] %s,%d: ec_request",
12710 UnMapId(Id), (char *)(FILE_), __LINE__));
12711
12712 Info = GOOD;
12713 result[0] = 0;
12714 if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER)))
12715 {
12716 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
12717 UnMapId(Id), (char *)(FILE_), __LINE__));
12718 Info = _FACILITY_NOT_SUPPORTED;
12719 }
12720 else
12721 {
12722 if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
12723 {
12724 if (api_parse(&msg[1].info[1], msg[1].length, "w", ec_parms))
12725 {
12726 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12727 UnMapId(Id), (char *)(FILE_), __LINE__));
12728 Info = _WRONG_MESSAGE_FORMAT;
12729 }
12730 else
12731 {
12732 if (plci == NULL)
12733 {
12734 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
12735 UnMapId(Id), (char *)(FILE_), __LINE__));
12736 Info = _WRONG_IDENTIFIER;
12737 }
12738 else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
12739 {
12740 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
12741 UnMapId(Id), (char *)(FILE_), __LINE__));
12742 Info = _WRONG_STATE;
12743 }
12744 else
12745 {
12746 plci->command = 0;
12747 plci->ec_cmd = GET_WORD(ec_parms[0].info);
12748 plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
12749 result[0] = 2;
12750 PUT_WORD(&result[1], EC_SUCCESS);
12751 if (msg[1].length >= 4)
12752 {
12753 opt = GET_WORD(&ec_parms[0].info[2]);
12754 plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
12755 LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
12756 if (!(opt & EC_DISABLE_NON_LINEAR_PROCESSING))
12757 plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
12758 if (opt & EC_DETECT_DISABLE_TONE)
12759 plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
12760 if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
12761 plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
12762 if (msg[1].length >= 6)
12763 {
12764 plci->ec_tail_length = GET_WORD(&ec_parms[0].info[4]);
12765 }
12766 }
12767 switch (plci->ec_cmd)
12768 {
12769 case EC_ENABLE_OPERATION:
12770 plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
12771 start_internal_command(Id, plci, ec_command);
12772 return (false);
12773
12774 case EC_DISABLE_OPERATION:
12775 plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
12776 LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
12777 LEC_RESET_COEFFICIENTS;
12778 start_internal_command(Id, plci, ec_command);
12779 return (false);
12780
12781 case EC_FREEZE_COEFFICIENTS:
12782 plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS;
12783 start_internal_command(Id, plci, ec_command);
12784 return (false);
12785
12786 case EC_RESUME_COEFFICIENT_UPDATE:
12787 plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
12788 start_internal_command(Id, plci, ec_command);
12789 return (false);
12790
12791 case EC_RESET_COEFFICIENTS:
12792 plci->ec_idi_options |= LEC_RESET_COEFFICIENTS;
12793 start_internal_command(Id, plci, ec_command);
12794 return (false);
12795
12796 default:
12797 dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
12798 UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd));
12799 PUT_WORD(&result[1], EC_UNSUPPORTED_OPERATION);
12800 }
12801 }
12802 }
12803 }
12804 else
12805 {
12806 if (api_parse(&msg[1].info[1], msg[1].length, "ws", ec_parms))
12807 {
12808 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12809 UnMapId(Id), (char *)(FILE_), __LINE__));
12810 Info = _WRONG_MESSAGE_FORMAT;
12811 }
12812 else
12813 {
12814 if (GET_WORD(ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES)
12815 {
12816 result[0] = 11;
12817 PUT_WORD(&result[1], EC_GET_SUPPORTED_SERVICES);
12818 result[3] = 8;
12819 PUT_WORD(&result[4], GOOD);
12820 PUT_WORD(&result[6], 0x0007);
12821 PUT_WORD(&result[8], LEC_MAX_SUPPORTED_TAIL_LENGTH);
12822 PUT_WORD(&result[10], 0);
12823 }
12824 else if (plci == NULL)
12825 {
12826 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
12827 UnMapId(Id), (char *)(FILE_), __LINE__));
12828 Info = _WRONG_IDENTIFIER;
12829 }
12830 else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
12831 {
12832 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
12833 UnMapId(Id), (char *)(FILE_), __LINE__));
12834 Info = _WRONG_STATE;
12835 }
12836 else
12837 {
12838 plci->command = 0;
12839 plci->ec_cmd = GET_WORD(ec_parms[0].info);
12840 plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
12841 result[0] = 5;
12842 PUT_WORD(&result[1], plci->ec_cmd);
12843 result[3] = 2;
12844 PUT_WORD(&result[4], GOOD);
12845 plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
12846 LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
12847 plci->ec_tail_length = 0;
12848 if (ec_parms[1].length >= 2)
12849 {
12850 opt = GET_WORD(&ec_parms[1].info[1]);
12851 if (opt & EC_ENABLE_NON_LINEAR_PROCESSING)
12852 plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
12853 if (opt & EC_DETECT_DISABLE_TONE)
12854 plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
12855 if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
12856 plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
12857 if (ec_parms[1].length >= 4)
12858 {
12859 plci->ec_tail_length = GET_WORD(&ec_parms[1].info[3]);
12860 }
12861 }
12862 switch (plci->ec_cmd)
12863 {
12864 case EC_ENABLE_OPERATION:
12865 plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
12866 start_internal_command(Id, plci, ec_command);
12867 return (false);
12868
12869 case EC_DISABLE_OPERATION:
12870 plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
12871 LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
12872 LEC_RESET_COEFFICIENTS;
12873 start_internal_command(Id, plci, ec_command);
12874 return (false);
12875
12876 default:
12877 dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
12878 UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd));
12879 PUT_WORD(&result[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP);
12880 }
12881 }
12882 }
12883 }
12884 }
12885 sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
12886 "wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
12887 PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
12888 return (false);
12889}
12890
12891
12892static void ec_indication(dword Id, PLCI *plci, byte *msg, word length)
12893{
12894 byte result[8];
12895
12896 dbug(1, dprintf("[%06lx] %s,%d: ec_indication",
12897 UnMapId(Id), (char *)(FILE_), __LINE__));
12898
12899 if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE))
12900 {
12901 if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
12902 {
12903 result[0] = 2;
12904 PUT_WORD(&result[1], 0);
12905 switch (msg[1])
12906 {
12907 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
12908 PUT_WORD(&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
12909 break;
12910 case LEC_DISABLE_TYPE_REVERSED_2100HZ:
12911 PUT_WORD(&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
12912 break;
12913 case LEC_DISABLE_RELEASED:
12914 PUT_WORD(&result[1], EC_BYPASS_RELEASED);
12915 break;
12916 }
12917 }
12918 else
12919 {
12920 result[0] = 5;
12921 PUT_WORD(&result[1], EC_BYPASS_INDICATION);
12922 result[3] = 2;
12923 PUT_WORD(&result[4], 0);
12924 switch (msg[1])
12925 {
12926 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
12927 PUT_WORD(&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
12928 break;
12929 case LEC_DISABLE_TYPE_REVERSED_2100HZ:
12930 PUT_WORD(&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
12931 break;
12932 case LEC_DISABLE_RELEASED:
12933 PUT_WORD(&result[4], EC_BYPASS_RELEASED);
12934 break;
12935 }
12936 }
12937 sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
12938 PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
12939 }
12940}
12941
12942
12943
12944/*------------------------------------------------------------------*/
12945/* Advanced voice */
12946/*------------------------------------------------------------------*/
12947
12948static void adv_voice_write_coefs(PLCI *plci, word write_command)
12949{
12950 DIVA_CAPI_ADAPTER *a;
12951 word i;
12952 byte *p;
12953
12954 word w, n, j, k;
12955 byte ch_map[MIXER_CHANNELS_BRI];
12956
12957 byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2];
12958
12959 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_write_coefs %d",
12960 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
12961 (char *)(FILE_), __LINE__, write_command));
12962
12963 a = plci->adapter;
12964 p = coef_buffer + 1;
12965 *(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS;
12966 i = 0;
12967 while (i + sizeof(word) <= a->adv_voice_coef_length)
12968 {
12969 PUT_WORD(p, GET_WORD(a->adv_voice_coef_buffer + i));
12970 p += 2;
12971 i += 2;
12972 }
12973 while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word))
12974 {
12975 PUT_WORD(p, 0x8000);
12976 p += 2;
12977 i += 2;
12978 }
12979
12980 if (!a->li_pri && (plci->li_bchannel_id == 0))
12981 {
12982 if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL))
12983 {
12984 plci->li_bchannel_id = 1;
12985 li_config_table[a->li_base].plci = plci;
12986 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
12987 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
12988 (char *)(FILE_), __LINE__, plci->li_bchannel_id));
12989 }
12990 else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL))
12991 {
12992 plci->li_bchannel_id = 2;
12993 li_config_table[a->li_base + 1].plci = plci;
12994 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
12995 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
12996 (char *)(FILE_), __LINE__, plci->li_bchannel_id));
12997 }
12998 }
12999 if (!a->li_pri && (plci->li_bchannel_id != 0)
13000 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
13001 {
13002 i = a->li_base + (plci->li_bchannel_id - 1);
13003 switch (write_command)
13004 {
13005 case ADV_VOICE_WRITE_ACTIVATION:
13006 j = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
13007 k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
13008 if (!(plci->B1_facilities & B1_FACILITY_MIXER))
13009 {
13010 li_config_table[j].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
13011 li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
13012 }
13013 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
13014 {
13015 li_config_table[k].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
13016 li_config_table[i].flag_table[k] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
13017 li_config_table[k].flag_table[j] |= LI_FLAG_CONFERENCE;
13018 li_config_table[j].flag_table[k] |= LI_FLAG_CONFERENCE;
13019 }
13020 mixer_calculate_coefs(a);
13021 li_config_table[i].curchnl = li_config_table[i].channel;
13022 li_config_table[j].curchnl = li_config_table[j].channel;
13023 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
13024 li_config_table[k].curchnl = li_config_table[k].channel;
13025 break;
13026
13027 case ADV_VOICE_WRITE_DEACTIVATION:
13028 for (j = 0; j < li_total_channels; j++)
13029 {
13030 li_config_table[i].flag_table[j] = 0;
13031 li_config_table[j].flag_table[i] = 0;
13032 }
13033 k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
13034 for (j = 0; j < li_total_channels; j++)
13035 {
13036 li_config_table[k].flag_table[j] = 0;
13037 li_config_table[j].flag_table[k] = 0;
13038 }
13039 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
13040 {
13041 k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
13042 for (j = 0; j < li_total_channels; j++)
13043 {
13044 li_config_table[k].flag_table[j] = 0;
13045 li_config_table[j].flag_table[k] = 0;
13046 }
13047 }
13048 mixer_calculate_coefs(a);
13049 break;
13050 }
13051 if (plci->B1_facilities & B1_FACILITY_MIXER)
13052 {
13053 w = 0;
13054 if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)
13055 w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
13056 if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
13057 w |= MIXER_FEATURE_ENABLE_TX_DATA;
13058 if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
13059 w |= MIXER_FEATURE_ENABLE_RX_DATA;
13060 *(p++) = (byte) w;
13061 *(p++) = (byte)(w >> 8);
13062 for (j = 0; j < sizeof(ch_map); j += 2)
13063 {
13064 ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1));
13065 ch_map[j + 1] = (byte)(j + (2 - plci->li_bchannel_id));
13066 }
13067 for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
13068 {
13069 i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
13070 j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
13071 if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
13072 {
13073 *(p++) = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
13074 w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
13075 li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
13076 }
13077 else
13078 {
13079 *(p++) = (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n < a->adv_voice_coef_length) ?
13080 a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n] : 0x00;
13081 }
13082 }
13083 }
13084 else
13085 {
13086 for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
13087 *(p++) = a->adv_voice_coef_buffer[i];
13088 }
13089 }
13090 else
13091
13092 {
13093 for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
13094 *(p++) = a->adv_voice_coef_buffer[i];
13095 }
13096 coef_buffer[0] = (p - coef_buffer) - 1;
13097 add_p(plci, FTY, coef_buffer);
13098 sig_req(plci, TEL_CTRL, 0);
13099 send_req(plci);
13100}
13101
13102
13103static void adv_voice_clear_config(PLCI *plci)
13104{
13105 DIVA_CAPI_ADAPTER *a;
13106
13107 word i, j;
13108
13109
13110 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_clear_config",
13111 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
13112 (char *)(FILE_), __LINE__));
13113
13114 a = plci->adapter;
13115 if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
13116 {
13117 a->adv_voice_coef_length = 0;
13118
13119 if (!a->li_pri && (plci->li_bchannel_id != 0)
13120 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
13121 {
13122 i = a->li_base + (plci->li_bchannel_id - 1);
13123 li_config_table[i].curchnl = 0;
13124 li_config_table[i].channel = 0;
13125 li_config_table[i].chflags = 0;
13126 for (j = 0; j < li_total_channels; j++)
13127 {
13128 li_config_table[i].flag_table[j] = 0;
13129 li_config_table[j].flag_table[i] = 0;
13130 li_config_table[i].coef_table[j] = 0;
13131 li_config_table[j].coef_table[i] = 0;
13132 }
13133 li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
13134 i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
13135 li_config_table[i].curchnl = 0;
13136 li_config_table[i].channel = 0;
13137 li_config_table[i].chflags = 0;
13138 for (j = 0; j < li_total_channels; j++)
13139 {
13140 li_config_table[i].flag_table[j] = 0;
13141 li_config_table[j].flag_table[i] = 0;
13142 li_config_table[i].coef_table[j] = 0;
13143 li_config_table[j].coef_table[i] = 0;
13144 }
13145 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
13146 {
13147 i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
13148 li_config_table[i].curchnl = 0;
13149 li_config_table[i].channel = 0;
13150 li_config_table[i].chflags = 0;
13151 for (j = 0; j < li_total_channels; j++)
13152 {
13153 li_config_table[i].flag_table[j] = 0;
13154 li_config_table[j].flag_table[i] = 0;
13155 li_config_table[i].coef_table[j] = 0;
13156 li_config_table[j].coef_table[i] = 0;
13157 }
13158 }
13159 }
13160
13161 }
13162}
13163
13164
13165static void adv_voice_prepare_switch(dword Id, PLCI *plci)
13166{
13167
13168 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_prepare_switch",
13169 UnMapId(Id), (char *)(FILE_), __LINE__));
13170
13171}
13172
13173
13174static word adv_voice_save_config(dword Id, PLCI *plci, byte Rc)
13175{
13176
13177 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_save_config %02x %d",
13178 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
13179
13180 return (GOOD);
13181}
13182
13183
13184static word adv_voice_restore_config(dword Id, PLCI *plci, byte Rc)
13185{
13186 DIVA_CAPI_ADAPTER *a;
13187 word Info;
13188
13189 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_restore_config %02x %d",
13190 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
13191
13192 Info = GOOD;
13193 a = plci->adapter;
13194 if ((plci->B1_facilities & B1_FACILITY_VOICE)
13195 && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
13196 {
13197 switch (plci->adjust_b_state)
13198 {
13199 case ADJUST_B_RESTORE_VOICE_1:
13200 plci->internal_command = plci->adjust_b_command;
13201 if (plci->sig_req)
13202 {
13203 plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
13204 break;
13205 }
13206 adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE);
13207 plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2;
13208 break;
13209 case ADJUST_B_RESTORE_VOICE_2:
13210 if ((Rc != OK) && (Rc != OK_FC))
13211 {
13212 dbug(1, dprintf("[%06lx] %s,%d: Restore voice config failed %02x",
13213 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
13214 Info = _WRONG_STATE;
13215 break;
13216 }
13217 break;
13218 }
13219 }
13220 return (Info);
13221}
13222
13223
13224
13225
13226/*------------------------------------------------------------------*/
13227/* B1 resource switching */
13228/*------------------------------------------------------------------*/
13229
13230static byte b1_facilities_table[] =
13231{
13232 0x00, /* 0 No bchannel resources */
13233 0x00, /* 1 Codec (automatic law) */
13234 0x00, /* 2 Codec (A-law) */
13235 0x00, /* 3 Codec (y-law) */
13236 0x00, /* 4 HDLC for X.21 */
13237 0x00, /* 5 HDLC */
13238 0x00, /* 6 External Device 0 */
13239 0x00, /* 7 External Device 1 */
13240 0x00, /* 8 HDLC 56k */
13241 0x00, /* 9 Transparent */
13242 0x00, /* 10 Loopback to network */
13243 0x00, /* 11 Test pattern to net */
13244 0x00, /* 12 Rate adaptation sync */
13245 0x00, /* 13 Rate adaptation async */
13246 0x00, /* 14 R-Interface */
13247 0x00, /* 15 HDLC 128k leased line */
13248 0x00, /* 16 FAX */
13249 0x00, /* 17 Modem async */
13250 0x00, /* 18 Modem sync HDLC */
13251 0x00, /* 19 V.110 async HDLC */
13252 0x12, /* 20 Adv voice (Trans,mixer) */
13253 0x00, /* 21 Codec connected to IC */
13254 0x0c, /* 22 Trans,DTMF */
13255 0x1e, /* 23 Trans,DTMF+mixer */
13256 0x1f, /* 24 Trans,DTMF+mixer+local */
13257 0x13, /* 25 Trans,mixer+local */
13258 0x12, /* 26 HDLC,mixer */
13259 0x12, /* 27 HDLC 56k,mixer */
13260 0x2c, /* 28 Trans,LEC+DTMF */
13261 0x3e, /* 29 Trans,LEC+DTMF+mixer */
13262 0x3f, /* 30 Trans,LEC+DTMF+mixer+local */
13263 0x2c, /* 31 RTP,LEC+DTMF */
13264 0x3e, /* 32 RTP,LEC+DTMF+mixer */
13265 0x3f, /* 33 RTP,LEC+DTMF+mixer+local */
13266 0x00, /* 34 Signaling task */
13267 0x00, /* 35 PIAFS */
13268 0x0c, /* 36 Trans,DTMF+TONE */
13269 0x1e, /* 37 Trans,DTMF+TONE+mixer */
13270 0x1f /* 38 Trans,DTMF+TONE+mixer+local*/
13271};
13272
13273
13274static word get_b1_facilities(PLCI *plci, byte b1_resource)
13275{
13276 word b1_facilities;
13277
13278 b1_facilities = b1_facilities_table[b1_resource];
13279 if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25))
13280 {
13281
13282 if (!(((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
13283 || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE)))))
13284
13285 {
13286 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND)
13287 b1_facilities |= B1_FACILITY_DTMFX;
13288 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)
13289 b1_facilities |= B1_FACILITY_DTMFR;
13290 }
13291 }
13292 if ((b1_resource == 17) || (b1_resource == 18))
13293 {
13294 if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN))
13295 b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR;
13296 }
13297/*
13298 dbug (1, dprintf("[%06lx] %s,%d: get_b1_facilities %d %04x",
13299 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
13300 (char far *)(FILE_), __LINE__, b1_resource, b1_facilites));
13301*/
13302 return (b1_facilities);
13303}
13304
13305
13306static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities)
13307{
13308 byte b;
13309
13310 switch (b1_resource)
13311 {
13312 case 5:
13313 case 26:
13314 if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13315 b = 26;
13316 else
13317 b = 5;
13318 break;
13319
13320 case 8:
13321 case 27:
13322 if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13323 b = 27;
13324 else
13325 b = 8;
13326 break;
13327
13328 case 9:
13329 case 20:
13330 case 22:
13331 case 23:
13332 case 24:
13333 case 25:
13334 case 28:
13335 case 29:
13336 case 30:
13337 case 36:
13338 case 37:
13339 case 38:
13340 if (b1_facilities & B1_FACILITY_EC)
13341 {
13342 if (b1_facilities & B1_FACILITY_LOCAL)
13343 b = 30;
13344 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13345 b = 29;
13346 else
13347 b = 28;
13348 }
13349
13350 else if ((b1_facilities & (B1_FACILITY_DTMFX | B1_FACILITY_DTMFR | B1_FACILITY_MIXER))
13351 && (((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
13352 || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE)))))
13353 {
13354 if (b1_facilities & B1_FACILITY_LOCAL)
13355 b = 38;
13356 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13357 b = 37;
13358 else
13359 b = 36;
13360 }
13361
13362 else if (((plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
13363 && !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
13364 || ((b1_facilities & B1_FACILITY_DTMFR)
13365 && ((b1_facilities & B1_FACILITY_MIXER)
13366 || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)))
13367 || ((b1_facilities & B1_FACILITY_DTMFX)
13368 && ((b1_facilities & B1_FACILITY_MIXER)
13369 || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND))))
13370 {
13371 if (b1_facilities & B1_FACILITY_LOCAL)
13372 b = 24;
13373 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13374 b = 23;
13375 else
13376 b = 22;
13377 }
13378 else
13379 {
13380 if (b1_facilities & B1_FACILITY_LOCAL)
13381 b = 25;
13382 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13383 b = 20;
13384 else
13385 b = 9;
13386 }
13387 break;
13388
13389 case 31:
13390 case 32:
13391 case 33:
13392 if (b1_facilities & B1_FACILITY_LOCAL)
13393 b = 33;
13394 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13395 b = 32;
13396 else
13397 b = 31;
13398 break;
13399
13400 default:
13401 b = b1_resource;
13402 }
13403 dbug(1, dprintf("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x",
13404 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
13405 (char *)(FILE_), __LINE__,
13406 b1_resource, b1_facilities, b, get_b1_facilities(plci, b)));
13407 return (b);
13408}
13409
13410
13411static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities)
13412{
13413 word removed_facilities;
13414
13415 dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x",
13416 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
13417 (char *)(FILE_), __LINE__, new_b1_resource, new_b1_facilities,
13418 new_b1_facilities & get_b1_facilities(plci, new_b1_resource)));
13419
13420 new_b1_facilities &= get_b1_facilities(plci, new_b1_resource);
13421 removed_facilities = plci->B1_facilities & ~new_b1_facilities;
13422
13423 if (removed_facilities & B1_FACILITY_EC)
13424 ec_clear_config(plci);
13425
13426
13427 if (removed_facilities & B1_FACILITY_DTMFR)
13428 {
13429 dtmf_rec_clear_config(plci);
13430 dtmf_parameter_clear_config(plci);
13431 }
13432 if (removed_facilities & B1_FACILITY_DTMFX)
13433 dtmf_send_clear_config(plci);
13434
13435
13436 if (removed_facilities & B1_FACILITY_MIXER)
13437 mixer_clear_config(plci);
13438
13439 if (removed_facilities & B1_FACILITY_VOICE)
13440 adv_voice_clear_config(plci);
13441 plci->B1_facilities = new_b1_facilities;
13442}
13443
13444
13445static void adjust_b_clear(PLCI *plci)
13446{
13447
13448 dbug(1, dprintf("[%06lx] %s,%d: adjust_b_clear",
13449 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
13450 (char *)(FILE_), __LINE__));
13451
13452 plci->adjust_b_restore = false;
13453}
13454
13455
13456static word adjust_b_process(dword Id, PLCI *plci, byte Rc)
13457{
13458 word Info;
13459 byte b1_resource;
13460 NCCI *ncci_ptr;
13461 API_PARSE bp[2];
13462
13463 dbug(1, dprintf("[%06lx] %s,%d: adjust_b_process %02x %d",
13464 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
13465
13466 Info = GOOD;
13467 switch (plci->adjust_b_state)
13468 {
13469 case ADJUST_B_START:
13470 if ((plci->adjust_b_parms_msg == NULL)
13471 && (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
13472 && ((plci->adjust_b_mode & ~(ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 |
13473 ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_RESTORE)) == 0))
13474 {
13475 b1_resource = (plci->adjust_b_mode == ADJUST_B_MODE_NO_RESOURCE) ?
13476 0 : add_b1_facilities(plci, plci->B1_resource, plci->adjust_b_facilities);
13477 if (b1_resource == plci->B1_resource)
13478 {
13479 adjust_b1_facilities(plci, b1_resource, plci->adjust_b_facilities);
13480 break;
13481 }
13482 if (plci->adjust_b_facilities & ~get_b1_facilities(plci, b1_resource))
13483 {
13484 dbug(1, dprintf("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x",
13485 UnMapId(Id), (char *)(FILE_), __LINE__,
13486 plci->B1_resource, b1_resource, plci->adjust_b_facilities));
13487 Info = _WRONG_STATE;
13488 break;
13489 }
13490 }
13491 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13492 {
13493
13494 mixer_prepare_switch(Id, plci);
13495
13496
13497 dtmf_prepare_switch(Id, plci);
13498 dtmf_parameter_prepare_switch(Id, plci);
13499
13500
13501 ec_prepare_switch(Id, plci);
13502
13503 adv_voice_prepare_switch(Id, plci);
13504 }
13505 plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1;
13506 Rc = OK;
13507 /* fall through */
13508 case ADJUST_B_SAVE_MIXER_1:
13509 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13510 {
13511
13512 Info = mixer_save_config(Id, plci, Rc);
13513 if ((Info != GOOD) || plci->internal_command)
13514 break;
13515
13516 }
13517 plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1;
13518 Rc = OK;
13519 /* fall through */
13520 case ADJUST_B_SAVE_DTMF_1:
13521 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13522 {
13523
13524 Info = dtmf_save_config(Id, plci, Rc);
13525 if ((Info != GOOD) || plci->internal_command)
13526 break;
13527
13528 }
13529 plci->adjust_b_state = ADJUST_B_REMOVE_L23_1;
13530 /* fall through */
13531 case ADJUST_B_REMOVE_L23_1:
13532 if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
13533 && plci->NL.Id && !plci->nl_remove_id)
13534 {
13535 plci->internal_command = plci->adjust_b_command;
13536 if (plci->adjust_b_ncci != 0)
13537 {
13538 ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]);
13539 while (ncci_ptr->data_pending)
13540 {
13541 plci->data_sent_ptr = ncci_ptr->DBuffer[ncci_ptr->data_out].P;
13542 data_rc(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
13543 }
13544 while (ncci_ptr->data_ack_pending)
13545 data_ack(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
13546 }
13547 nl_req_ncci(plci, REMOVE,
13548 (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0));
13549 send_req(plci);
13550 plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
13551 break;
13552 }
13553 plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
13554 Rc = OK;
13555 /* fall through */
13556 case ADJUST_B_REMOVE_L23_2:
13557 if ((Rc != OK) && (Rc != OK_FC))
13558 {
13559 dbug(1, dprintf("[%06lx] %s,%d: Adjust B remove failed %02x",
13560 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
13561 Info = _WRONG_STATE;
13562 break;
13563 }
13564 if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
13565 {
13566 if (plci_nl_busy(plci))
13567 {
13568 plci->internal_command = plci->adjust_b_command;
13569 break;
13570 }
13571 }
13572 plci->adjust_b_state = ADJUST_B_SAVE_EC_1;
13573 Rc = OK;
13574 /* fall through */
13575 case ADJUST_B_SAVE_EC_1:
13576 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13577 {
13578
13579 Info = ec_save_config(Id, plci, Rc);
13580 if ((Info != GOOD) || plci->internal_command)
13581 break;
13582
13583 }
13584 plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1;
13585 Rc = OK;
13586 /* fall through */
13587 case ADJUST_B_SAVE_DTMF_PARAMETER_1:
13588 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13589 {
13590
13591 Info = dtmf_parameter_save_config(Id, plci, Rc);
13592 if ((Info != GOOD) || plci->internal_command)
13593 break;
13594
13595 }
13596 plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1;
13597 Rc = OK;
13598 /* fall through */
13599 case ADJUST_B_SAVE_VOICE_1:
13600 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13601 {
13602 Info = adv_voice_save_config(Id, plci, Rc);
13603 if ((Info != GOOD) || plci->internal_command)
13604 break;
13605 }
13606 plci->adjust_b_state = ADJUST_B_SWITCH_L1_1;
13607 /* fall through */
13608 case ADJUST_B_SWITCH_L1_1:
13609 if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
13610 {
13611 if (plci->sig_req)
13612 {
13613 plci->internal_command = plci->adjust_b_command;
13614 break;
13615 }
13616 if (plci->adjust_b_parms_msg != NULL)
13617 api_load_msg(plci->adjust_b_parms_msg, bp);
13618 else
13619 api_load_msg(&plci->B_protocol, bp);
13620 Info = add_b1(plci, bp,
13621 (word)((plci->adjust_b_mode & ADJUST_B_MODE_NO_RESOURCE) ? 2 : 0),
13622 plci->adjust_b_facilities);
13623 if (Info != GOOD)
13624 {
13625 dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x",
13626 UnMapId(Id), (char *)(FILE_), __LINE__,
13627 plci->B1_resource, plci->adjust_b_facilities));
13628 break;
13629 }
13630 plci->internal_command = plci->adjust_b_command;
13631 sig_req(plci, RESOURCES, 0);
13632 send_req(plci);
13633 plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
13634 break;
13635 }
13636 plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
13637 Rc = OK;
13638 /* fall through */
13639 case ADJUST_B_SWITCH_L1_2:
13640 if ((Rc != OK) && (Rc != OK_FC))
13641 {
13642 dbug(1, dprintf("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x",
13643 UnMapId(Id), (char *)(FILE_), __LINE__,
13644 Rc, plci->B1_resource, plci->adjust_b_facilities));
13645 Info = _WRONG_STATE;
13646 break;
13647 }
13648 plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
13649 Rc = OK;
13650 /* fall through */
13651 case ADJUST_B_RESTORE_VOICE_1:
13652 case ADJUST_B_RESTORE_VOICE_2:
13653 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13654 {
13655 Info = adv_voice_restore_config(Id, plci, Rc);
13656 if ((Info != GOOD) || plci->internal_command)
13657 break;
13658 }
13659 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
13660 Rc = OK;
13661 /* fall through */
13662 case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
13663 case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
13664 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13665 {
13666
13667 Info = dtmf_parameter_restore_config(Id, plci, Rc);
13668 if ((Info != GOOD) || plci->internal_command)
13669 break;
13670
13671 }
13672 plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
13673 Rc = OK;
13674 /* fall through */
13675 case ADJUST_B_RESTORE_EC_1:
13676 case ADJUST_B_RESTORE_EC_2:
13677 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13678 {
13679
13680 Info = ec_restore_config(Id, plci, Rc);
13681 if ((Info != GOOD) || plci->internal_command)
13682 break;
13683
13684 }
13685 plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1;
13686 /* fall through */
13687 case ADJUST_B_ASSIGN_L23_1:
13688 if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
13689 {
13690 if (plci_nl_busy(plci))
13691 {
13692 plci->internal_command = plci->adjust_b_command;
13693 break;
13694 }
13695 if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
13696 plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
13697 if (plci->adjust_b_parms_msg != NULL)
13698 api_load_msg(plci->adjust_b_parms_msg, bp);
13699 else
13700 api_load_msg(&plci->B_protocol, bp);
13701 Info = add_b23(plci, bp);
13702 if (Info != GOOD)
13703 {
13704 dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x",
13705 UnMapId(Id), (char *)(FILE_), __LINE__, Info));
13706 break;
13707 }
13708 plci->internal_command = plci->adjust_b_command;
13709 nl_req_ncci(plci, ASSIGN, 0);
13710 send_req(plci);
13711 plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
13712 break;
13713 }
13714 plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
13715 Rc = ASSIGN_OK;
13716 /* fall through */
13717 case ADJUST_B_ASSIGN_L23_2:
13718 if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK))
13719 {
13720 dbug(1, dprintf("[%06lx] %s,%d: Adjust B assign failed %02x",
13721 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
13722 Info = _WRONG_STATE;
13723 break;
13724 }
13725 if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
13726 {
13727 if (Rc != ASSIGN_OK)
13728 {
13729 plci->internal_command = plci->adjust_b_command;
13730 break;
13731 }
13732 }
13733 if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT)
13734 {
13735 plci->adjust_b_restore = true;
13736 break;
13737 }
13738 plci->adjust_b_state = ADJUST_B_CONNECT_1;
13739 /* fall through */
13740 case ADJUST_B_CONNECT_1:
13741 if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
13742 {
13743 plci->internal_command = plci->adjust_b_command;
13744 if (plci_nl_busy(plci))
13745 break;
13746 nl_req_ncci(plci, N_CONNECT, 0);
13747 send_req(plci);
13748 plci->adjust_b_state = ADJUST_B_CONNECT_2;
13749 break;
13750 }
13751 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
13752 Rc = OK;
13753 /* fall through */
13754 case ADJUST_B_CONNECT_2:
13755 case ADJUST_B_CONNECT_3:
13756 case ADJUST_B_CONNECT_4:
13757 if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
13758 {
13759 dbug(1, dprintf("[%06lx] %s,%d: Adjust B connect failed %02x",
13760 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
13761 Info = _WRONG_STATE;
13762 break;
13763 }
13764 if (Rc == OK)
13765 {
13766 if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
13767 {
13768 get_ncci(plci, (byte)(Id >> 16), plci->adjust_b_ncci);
13769 Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16);
13770 }
13771 if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
13772 plci->adjust_b_state = ADJUST_B_CONNECT_3;
13773 else if (plci->adjust_b_state == ADJUST_B_CONNECT_4)
13774 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
13775 }
13776 else if (Rc == 0)
13777 {
13778 if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
13779 plci->adjust_b_state = ADJUST_B_CONNECT_4;
13780 else if (plci->adjust_b_state == ADJUST_B_CONNECT_3)
13781 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
13782 }
13783 if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1)
13784 {
13785 plci->internal_command = plci->adjust_b_command;
13786 break;
13787 }
13788 Rc = OK;
13789 /* fall through */
13790 case ADJUST_B_RESTORE_DTMF_1:
13791 case ADJUST_B_RESTORE_DTMF_2:
13792 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13793 {
13794
13795 Info = dtmf_restore_config(Id, plci, Rc);
13796 if ((Info != GOOD) || plci->internal_command)
13797 break;
13798
13799 }
13800 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
13801 Rc = OK;
13802 /* fall through */
13803 case ADJUST_B_RESTORE_MIXER_1:
13804 case ADJUST_B_RESTORE_MIXER_2:
13805 case ADJUST_B_RESTORE_MIXER_3:
13806 case ADJUST_B_RESTORE_MIXER_4:
13807 case ADJUST_B_RESTORE_MIXER_5:
13808 case ADJUST_B_RESTORE_MIXER_6:
13809 case ADJUST_B_RESTORE_MIXER_7:
13810 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13811 {
13812
13813 Info = mixer_restore_config(Id, plci, Rc);
13814 if ((Info != GOOD) || plci->internal_command)
13815 break;
13816
13817 }
13818 plci->adjust_b_state = ADJUST_B_END;
13819 case ADJUST_B_END:
13820 break;
13821 }
13822 return (Info);
13823}
13824
13825
13826static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command)
13827{
13828
13829 dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_resource %d %04x",
13830 UnMapId(Id), (char *)(FILE_), __LINE__,
13831 plci->B1_resource, b1_facilities));
13832
13833 plci->adjust_b_parms_msg = bp_msg;
13834 plci->adjust_b_facilities = b1_facilities;
13835 plci->adjust_b_command = internal_command;
13836 plci->adjust_b_ncci = (word)(Id >> 16);
13837 if ((bp_msg == NULL) && (plci->B1_resource == 0))
13838 plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_SWITCH_L1;
13839 else
13840 plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | ADJUST_B_MODE_RESTORE;
13841 plci->adjust_b_state = ADJUST_B_START;
13842 dbug(1, dprintf("[%06lx] %s,%d: Adjust B1 resource %d %04x...",
13843 UnMapId(Id), (char *)(FILE_), __LINE__,
13844 plci->B1_resource, b1_facilities));
13845}
13846
13847
13848static void adjust_b_restore(dword Id, PLCI *plci, byte Rc)
13849{
13850 word internal_command;
13851
13852 dbug(1, dprintf("[%06lx] %s,%d: adjust_b_restore %02x %04x",
13853 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
13854
13855 internal_command = plci->internal_command;
13856 plci->internal_command = 0;
13857 switch (internal_command)
13858 {
13859 default:
13860 plci->command = 0;
13861 if (plci->req_in != 0)
13862 {
13863 plci->internal_command = ADJUST_B_RESTORE_1;
13864 break;
13865 }
13866 Rc = OK;
13867 /* fall through */
13868 case ADJUST_B_RESTORE_1:
13869 if ((Rc != OK) && (Rc != OK_FC))
13870 {
13871 dbug(1, dprintf("[%06lx] %s,%d: Adjust B enqueued failed %02x",
13872 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
13873 }
13874 plci->adjust_b_parms_msg = NULL;
13875 plci->adjust_b_facilities = plci->B1_facilities;
13876 plci->adjust_b_command = ADJUST_B_RESTORE_2;
13877 plci->adjust_b_ncci = (word)(Id >> 16);
13878 plci->adjust_b_mode = ADJUST_B_MODE_RESTORE;
13879 plci->adjust_b_state = ADJUST_B_START;
13880 dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore...",
13881 UnMapId(Id), (char *)(FILE_), __LINE__));
13882 /* fall through */
13883 case ADJUST_B_RESTORE_2:
13884 if (adjust_b_process(Id, plci, Rc) != GOOD)
13885 {
13886 dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore failed",
13887 UnMapId(Id), (char *)(FILE_), __LINE__));
13888 }
13889 if (plci->internal_command)
13890 break;
13891 break;
13892 }
13893}
13894
13895
13896static void reset_b3_command(dword Id, PLCI *plci, byte Rc)
13897{
13898 word Info;
13899 word internal_command;
13900
13901 dbug(1, dprintf("[%06lx] %s,%d: reset_b3_command %02x %04x",
13902 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
13903
13904 Info = GOOD;
13905 internal_command = plci->internal_command;
13906 plci->internal_command = 0;
13907 switch (internal_command)
13908 {
13909 default:
13910 plci->command = 0;
13911 plci->adjust_b_parms_msg = NULL;
13912 plci->adjust_b_facilities = plci->B1_facilities;
13913 plci->adjust_b_command = RESET_B3_COMMAND_1;
13914 plci->adjust_b_ncci = (word)(Id >> 16);
13915 plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_CONNECT;
13916 plci->adjust_b_state = ADJUST_B_START;
13917 dbug(1, dprintf("[%06lx] %s,%d: Reset B3...",
13918 UnMapId(Id), (char *)(FILE_), __LINE__));
13919 /* fall through */
13920 case RESET_B3_COMMAND_1:
13921 Info = adjust_b_process(Id, plci, Rc);
13922 if (Info != GOOD)
13923 {
13924 dbug(1, dprintf("[%06lx] %s,%d: Reset failed",
13925 UnMapId(Id), (char *)(FILE_), __LINE__));
13926 break;
13927 }
13928 if (plci->internal_command)
13929 return;
13930 break;
13931 }
13932/* sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/
13933 sendf(plci->appl, _RESET_B3_I, Id, 0, "s", "");
13934}
13935
13936
13937static void select_b_command(dword Id, PLCI *plci, byte Rc)
13938{
13939 word Info;
13940 word internal_command;
13941 byte esc_chi[3];
13942
13943 dbug(1, dprintf("[%06lx] %s,%d: select_b_command %02x %04x",
13944 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
13945
13946 Info = GOOD;
13947 internal_command = plci->internal_command;
13948 plci->internal_command = 0;
13949 switch (internal_command)
13950 {
13951 default:
13952 plci->command = 0;
13953 plci->adjust_b_parms_msg = &plci->saved_msg;
13954 if ((plci->tel == ADV_VOICE) && (plci == plci->adapter->AdvSignalPLCI))
13955 plci->adjust_b_facilities = plci->B1_facilities | B1_FACILITY_VOICE;
13956 else
13957 plci->adjust_b_facilities = plci->B1_facilities & ~B1_FACILITY_VOICE;
13958 plci->adjust_b_command = SELECT_B_COMMAND_1;
13959 plci->adjust_b_ncci = (word)(Id >> 16);
13960 if (plci->saved_msg.parms[0].length == 0)
13961 {
13962 plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
13963 ADJUST_B_MODE_NO_RESOURCE;
13964 }
13965 else
13966 {
13967 plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
13968 ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
13969 }
13970 plci->adjust_b_state = ADJUST_B_START;
13971 dbug(1, dprintf("[%06lx] %s,%d: Select B protocol...",
13972 UnMapId(Id), (char *)(FILE_), __LINE__));
13973 /* fall through */
13974 case SELECT_B_COMMAND_1:
13975 Info = adjust_b_process(Id, plci, Rc);
13976 if (Info != GOOD)
13977 {
13978 dbug(1, dprintf("[%06lx] %s,%d: Select B protocol failed",
13979 UnMapId(Id), (char *)(FILE_), __LINE__));
13980 break;
13981 }
13982 if (plci->internal_command)
13983 return;
13984 if (plci->tel == ADV_VOICE)
13985 {
13986 esc_chi[0] = 0x02;
13987 esc_chi[1] = 0x18;
13988 esc_chi[2] = plci->b_channel;
13989 SetVoiceChannel(plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter);
13990 }
13991 break;
13992 }
13993 sendf(plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info);
13994}
13995
13996
13997static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc)
13998{
13999 word internal_command;
14000
14001 dbug(1, dprintf("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
14002 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14003
14004 internal_command = plci->internal_command;
14005 plci->internal_command = 0;
14006 switch (internal_command)
14007 {
14008 default:
14009 plci->command = 0; /* fall through */
14010 case FAX_CONNECT_ACK_COMMAND_1:
14011 if (plci_nl_busy(plci))
14012 {
14013 plci->internal_command = FAX_CONNECT_ACK_COMMAND_1;
14014 return;
14015 }
14016 plci->internal_command = FAX_CONNECT_ACK_COMMAND_2;
14017 plci->NData[0].P = plci->fax_connect_info_buffer;
14018 plci->NData[0].PLength = plci->fax_connect_info_length;
14019 plci->NL.X = plci->NData;
14020 plci->NL.ReqCh = 0;
14021 plci->NL.Req = plci->nl_req = (byte) N_CONNECT_ACK;
14022 plci->adapter->request(&plci->NL);
14023 return;
14024 case FAX_CONNECT_ACK_COMMAND_2:
14025 if ((Rc != OK) && (Rc != OK_FC))
14026 {
14027 dbug(1, dprintf("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x",
14028 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
14029 break;
14030 }
14031 }
14032 if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
14033 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
14034 {
14035 if (plci->B3_prot == 4)
14036 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
14037 else
14038 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
14039 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
14040 }
14041}
14042
14043
14044static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc)
14045{
14046 word internal_command;
14047
14048 dbug(1, dprintf("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
14049 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14050
14051 internal_command = plci->internal_command;
14052 plci->internal_command = 0;
14053 switch (internal_command)
14054 {
14055 default:
14056 plci->command = 0;
14057 /* fall through */
14058 case FAX_EDATA_ACK_COMMAND_1:
14059 if (plci_nl_busy(plci))
14060 {
14061 plci->internal_command = FAX_EDATA_ACK_COMMAND_1;
14062 return;
14063 }
14064 plci->internal_command = FAX_EDATA_ACK_COMMAND_2;
14065 plci->NData[0].P = plci->fax_connect_info_buffer;
14066 plci->NData[0].PLength = plci->fax_edata_ack_length;
14067 plci->NL.X = plci->NData;
14068 plci->NL.ReqCh = 0;
14069 plci->NL.Req = plci->nl_req = (byte) N_EDATA;
14070 plci->adapter->request(&plci->NL);
14071 return;
14072 case FAX_EDATA_ACK_COMMAND_2:
14073 if ((Rc != OK) && (Rc != OK_FC))
14074 {
14075 dbug(1, dprintf("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x",
14076 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
14077 break;
14078 }
14079 }
14080}
14081
14082
14083static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc)
14084{
14085 word Info;
14086 word internal_command;
14087
14088 dbug(1, dprintf("[%06lx] %s,%d: fax_connect_info_command %02x %04x",
14089 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14090
14091 Info = GOOD;
14092 internal_command = plci->internal_command;
14093 plci->internal_command = 0;
14094 switch (internal_command)
14095 {
14096 default:
14097 plci->command = 0; /* fall through */
14098 case FAX_CONNECT_INFO_COMMAND_1:
14099 if (plci_nl_busy(plci))
14100 {
14101 plci->internal_command = FAX_CONNECT_INFO_COMMAND_1;
14102 return;
14103 }
14104 plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
14105 plci->NData[0].P = plci->fax_connect_info_buffer;
14106 plci->NData[0].PLength = plci->fax_connect_info_length;
14107 plci->NL.X = plci->NData;
14108 plci->NL.ReqCh = 0;
14109 plci->NL.Req = plci->nl_req = (byte) N_EDATA;
14110 plci->adapter->request(&plci->NL);
14111 return;
14112 case FAX_CONNECT_INFO_COMMAND_2:
14113 if ((Rc != OK) && (Rc != OK_FC))
14114 {
14115 dbug(1, dprintf("[%06lx] %s,%d: FAX setting connect info failed %02x",
14116 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
14117 Info = _WRONG_STATE;
14118 break;
14119 }
14120 if (plci_nl_busy(plci))
14121 {
14122 plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
14123 return;
14124 }
14125 plci->command = _CONNECT_B3_R;
14126 nl_req_ncci(plci, N_CONNECT, 0);
14127 send_req(plci);
14128 return;
14129 }
14130 sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
14131}
14132
14133
14134static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc)
14135{
14136 word Info;
14137 word internal_command;
14138
14139 dbug(1, dprintf("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x",
14140 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14141
14142 Info = GOOD;
14143 internal_command = plci->internal_command;
14144 plci->internal_command = 0;
14145 switch (internal_command)
14146 {
14147 default:
14148 plci->command = 0;
14149 plci->adjust_b_parms_msg = NULL;
14150 plci->adjust_b_facilities = plci->B1_facilities;
14151 plci->adjust_b_command = FAX_ADJUST_B23_COMMAND_1;
14152 plci->adjust_b_ncci = (word)(Id >> 16);
14153 plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23;
14154 plci->adjust_b_state = ADJUST_B_START;
14155 dbug(1, dprintf("[%06lx] %s,%d: FAX adjust B23...",
14156 UnMapId(Id), (char *)(FILE_), __LINE__));
14157 /* fall through */
14158 case FAX_ADJUST_B23_COMMAND_1:
14159 Info = adjust_b_process(Id, plci, Rc);
14160 if (Info != GOOD)
14161 {
14162 dbug(1, dprintf("[%06lx] %s,%d: FAX adjust failed",
14163 UnMapId(Id), (char *)(FILE_), __LINE__));
14164 break;
14165 }
14166 if (plci->internal_command)
14167 return;
14168 /* fall through */
14169 case FAX_ADJUST_B23_COMMAND_2:
14170 if (plci_nl_busy(plci))
14171 {
14172 plci->internal_command = FAX_ADJUST_B23_COMMAND_2;
14173 return;
14174 }
14175 plci->command = _CONNECT_B3_R;
14176 nl_req_ncci(plci, N_CONNECT, 0);
14177 send_req(plci);
14178 return;
14179 }
14180 sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
14181}
14182
14183
14184static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc)
14185{
14186 word internal_command;
14187
14188 dbug(1, dprintf("[%06lx] %s,%d: fax_disconnect_command %02x %04x",
14189 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14190
14191 internal_command = plci->internal_command;
14192 plci->internal_command = 0;
14193 switch (internal_command)
14194 {
14195 default:
14196 plci->command = 0;
14197 plci->internal_command = FAX_DISCONNECT_COMMAND_1;
14198 return;
14199 case FAX_DISCONNECT_COMMAND_1:
14200 case FAX_DISCONNECT_COMMAND_2:
14201 case FAX_DISCONNECT_COMMAND_3:
14202 if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
14203 {
14204 dbug(1, dprintf("[%06lx] %s,%d: FAX disconnect EDATA failed %02x",
14205 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
14206 break;
14207 }
14208 if (Rc == OK)
14209 {
14210 if ((internal_command == FAX_DISCONNECT_COMMAND_1)
14211 || (internal_command == FAX_DISCONNECT_COMMAND_2))
14212 {
14213 plci->internal_command = FAX_DISCONNECT_COMMAND_2;
14214 }
14215 }
14216 else if (Rc == 0)
14217 {
14218 if (internal_command == FAX_DISCONNECT_COMMAND_1)
14219 plci->internal_command = FAX_DISCONNECT_COMMAND_3;
14220 }
14221 return;
14222 }
14223}
14224
14225
14226
14227static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc)
14228{
14229 word Info;
14230 word internal_command;
14231
14232 dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x",
14233 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14234
14235 Info = GOOD;
14236 internal_command = plci->internal_command;
14237 plci->internal_command = 0;
14238 switch (internal_command)
14239 {
14240 default:
14241 plci->command = 0; /* fall through */
14242 case RTP_CONNECT_B3_REQ_COMMAND_1:
14243 if (plci_nl_busy(plci))
14244 {
14245 plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1;
14246 return;
14247 }
14248 plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
14249 nl_req_ncci(plci, N_CONNECT, 0);
14250 send_req(plci);
14251 return;
14252 case RTP_CONNECT_B3_REQ_COMMAND_2:
14253 if ((Rc != OK) && (Rc != OK_FC))
14254 {
14255 dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect info failed %02x",
14256 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
14257 Info = _WRONG_STATE;
14258 break;
14259 }
14260 if (plci_nl_busy(plci))
14261 {
14262 plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
14263 return;
14264 }
14265 plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_3;
14266 plci->NData[0].PLength = plci->internal_req_buffer[0];
14267 plci->NData[0].P = plci->internal_req_buffer + 1;
14268 plci->NL.X = plci->NData;
14269 plci->NL.ReqCh = 0;
14270 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
14271 plci->adapter->request(&plci->NL);
14272 break;
14273 case RTP_CONNECT_B3_REQ_COMMAND_3:
14274 return;
14275 }
14276 sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
14277}
14278
14279
14280static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc)
14281{
14282 word internal_command;
14283
14284 dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
14285 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14286
14287 internal_command = plci->internal_command;
14288 plci->internal_command = 0;
14289 switch (internal_command)
14290 {
14291 default:
14292 plci->command = 0; /* fall through */
14293 case RTP_CONNECT_B3_RES_COMMAND_1:
14294 if (plci_nl_busy(plci))
14295 {
14296 plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1;
14297 return;
14298 }
14299 plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
14300 nl_req_ncci(plci, N_CONNECT_ACK, (byte)(Id >> 16));
14301 send_req(plci);
14302 return;
14303 case RTP_CONNECT_B3_RES_COMMAND_2:
14304 if ((Rc != OK) && (Rc != OK_FC))
14305 {
14306 dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
14307 UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
14308 break;
14309 }
14310 if (plci_nl_busy(plci))
14311 {
14312 plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
14313 return;
14314 }
14315 sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
14316 plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_3;
14317 plci->NData[0].PLength = plci->internal_req_buffer[0];
14318 plci->NData[0].P = plci->internal_req_buffer + 1;
14319 plci->NL.X = plci->NData;
14320 plci->NL.ReqCh = 0;
14321 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
14322 plci->adapter->request(&plci->NL);
14323 return;
14324 case RTP_CONNECT_B3_RES_COMMAND_3:
14325 return;
14326 }
14327}
14328
14329
14330
14331static void hold_save_command(dword Id, PLCI *plci, byte Rc)
14332{
14333 byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
14334 word Info;
14335 word internal_command;
14336
14337 dbug(1, dprintf("[%06lx] %s,%d: hold_save_command %02x %04x",
14338 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14339
14340 Info = GOOD;
14341 internal_command = plci->internal_command;
14342 plci->internal_command = 0;
14343 switch (internal_command)
14344 {
14345 default:
14346 if (!plci->NL.Id)
14347 break;
14348 plci->command = 0;
14349 plci->adjust_b_parms_msg = NULL;
14350 plci->adjust_b_facilities = plci->B1_facilities;
14351 plci->adjust_b_command = HOLD_SAVE_COMMAND_1;
14352 plci->adjust_b_ncci = (word)(Id >> 16);
14353 plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23;
14354 plci->adjust_b_state = ADJUST_B_START;
14355 dbug(1, dprintf("[%06lx] %s,%d: HOLD save...",
14356 UnMapId(Id), (char *)(FILE_), __LINE__));
14357 /* fall through */
14358 case HOLD_SAVE_COMMAND_1:
14359 Info = adjust_b_process(Id, plci, Rc);
14360 if (Info != GOOD)
14361 {
14362 dbug(1, dprintf("[%06lx] %s,%d: HOLD save failed",
14363 UnMapId(Id), (char *)(FILE_), __LINE__));
14364 break;
14365 }
14366 if (plci->internal_command)
14367 return;
14368 }
14369 sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
14370}
14371
14372
14373static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc)
14374{
14375 byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/
14376 word Info;
14377 word internal_command;
14378
14379 dbug(1, dprintf("[%06lx] %s,%d: retrieve_restore_command %02x %04x",
14380 UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14381
14382 Info = GOOD;
14383 internal_command = plci->internal_command;
14384 plci->internal_command = 0;
14385 switch (internal_command)
14386 {
14387 default:
14388 plci->command = 0;
14389 plci->adjust_b_parms_msg = NULL;
14390 plci->adjust_b_facilities = plci->B1_facilities;
14391 plci->adjust_b_command = RETRIEVE_RESTORE_COMMAND_1;
14392 plci->adjust_b_ncci = (word)(Id >> 16);
14393 plci->adjust_b_mode = ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
14394 plci->adjust_b_state = ADJUST_B_START;
14395 dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore...",
14396 UnMapId(Id), (char *)(FILE_), __LINE__));
14397 /* fall through */
14398 case RETRIEVE_RESTORE_COMMAND_1:
14399 Info = adjust_b_process(Id, plci, Rc);
14400 if (Info != GOOD)
14401 {
14402 dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore failed",
14403 UnMapId(Id), (char *)(FILE_), __LINE__));
14404 break;
14405 }
14406 if (plci->internal_command)
14407 return;
14408 }
14409 sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
14410}
14411
14412
14413static void init_b1_config(PLCI *plci)
14414{
14415
14416 dbug(1, dprintf("[%06lx] %s,%d: init_b1_config",
14417 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
14418 (char *)(FILE_), __LINE__));
14419
14420 plci->B1_resource = 0;
14421 plci->B1_facilities = 0;
14422
14423 plci->li_bchannel_id = 0;
14424 mixer_clear_config(plci);
14425
14426
14427 ec_clear_config(plci);
14428
14429
14430 dtmf_rec_clear_config(plci);
14431 dtmf_send_clear_config(plci);
14432 dtmf_parameter_clear_config(plci);
14433
14434 adv_voice_clear_config(plci);
14435 adjust_b_clear(plci);
14436}
14437
14438
14439static void clear_b1_config(PLCI *plci)
14440{
14441
14442 dbug(1, dprintf("[%06lx] %s,%d: clear_b1_config",
14443 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
14444 (char *)(FILE_), __LINE__));
14445
14446 adv_voice_clear_config(plci);
14447 adjust_b_clear(plci);
14448
14449 ec_clear_config(plci);
14450
14451
14452 dtmf_rec_clear_config(plci);
14453 dtmf_send_clear_config(plci);
14454 dtmf_parameter_clear_config(plci);
14455
14456
14457 if ((plci->li_bchannel_id != 0)
14458 && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci))
14459 {
14460 mixer_clear_config(plci);
14461 li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = NULL;
14462 plci->li_bchannel_id = 0;
14463 }
14464
14465 plci->B1_resource = 0;
14466 plci->B1_facilities = 0;
14467}
14468
14469
14470/* -----------------------------------------------------------------
14471 XON protocol local helpers
14472 ----------------------------------------------------------------- */
14473static void channel_flow_control_remove(PLCI *plci) {
14474 DIVA_CAPI_ADAPTER *a = plci->adapter;
14475 word i;
14476 for (i = 1; i < MAX_NL_CHANNEL + 1; i++) {
14477 if (a->ch_flow_plci[i] == plci->Id) {
14478 a->ch_flow_plci[i] = 0;
14479 a->ch_flow_control[i] = 0;
14480 }
14481 }
14482}
14483
14484static void channel_x_on(PLCI *plci, byte ch) {
14485 DIVA_CAPI_ADAPTER *a = plci->adapter;
14486 if (a->ch_flow_control[ch] & N_XON_SENT) {
14487 a->ch_flow_control[ch] &= ~N_XON_SENT;
14488 }
14489}
14490
14491static void channel_x_off(PLCI *plci, byte ch, byte flag) {
14492 DIVA_CAPI_ADAPTER *a = plci->adapter;
14493 if ((a->ch_flow_control[ch] & N_RX_FLOW_CONTROL_MASK) == 0) {
14494 a->ch_flow_control[ch] |= (N_CH_XOFF | flag);
14495 a->ch_flow_plci[ch] = plci->Id;
14496 a->ch_flow_control_pending++;
14497 }
14498}
14499
14500static void channel_request_xon(PLCI *plci, byte ch) {
14501 DIVA_CAPI_ADAPTER *a = plci->adapter;
14502
14503 if (a->ch_flow_control[ch] & N_CH_XOFF) {
14504 a->ch_flow_control[ch] |= N_XON_REQ;
14505 a->ch_flow_control[ch] &= ~N_CH_XOFF;
14506 a->ch_flow_control[ch] &= ~N_XON_CONNECT_IND;
14507 }
14508}
14509
14510static void channel_xmit_extended_xon(PLCI *plci) {
14511 DIVA_CAPI_ADAPTER *a;
14512 int max_ch = ARRAY_SIZE(a->ch_flow_control);
14513 int i, one_requested = 0;
14514
14515 if ((!plci) || (!plci->Id) || ((a = plci->adapter) == NULL)) {
14516 return;
14517 }
14518
14519 for (i = 0; i < max_ch; i++) {
14520 if ((a->ch_flow_control[i] & N_CH_XOFF) &&
14521 (a->ch_flow_control[i] & N_XON_CONNECT_IND) &&
14522 (plci->Id == a->ch_flow_plci[i])) {
14523 channel_request_xon(plci, (byte)i);
14524 one_requested = 1;
14525 }
14526 }
14527
14528 if (one_requested) {
14529 channel_xmit_xon(plci);
14530 }
14531}
14532
14533/*
14534 Try to xmit next X_ON
14535*/
14536static int find_channel_with_pending_x_on(DIVA_CAPI_ADAPTER *a, PLCI *plci) {
14537 int max_ch = ARRAY_SIZE(a->ch_flow_control);
14538 int i;
14539
14540 if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) {
14541 return (0);
14542 }
14543
14544 if (a->last_flow_control_ch >= max_ch) {
14545 a->last_flow_control_ch = 1;
14546 }
14547 for (i = a->last_flow_control_ch; i < max_ch; i++) {
14548 if ((a->ch_flow_control[i] & N_XON_REQ) &&
14549 (plci->Id == a->ch_flow_plci[i])) {
14550 a->last_flow_control_ch = i + 1;
14551 return (i);
14552 }
14553 }
14554
14555 for (i = 1; i < a->last_flow_control_ch; i++) {
14556 if ((a->ch_flow_control[i] & N_XON_REQ) &&
14557 (plci->Id == a->ch_flow_plci[i])) {
14558 a->last_flow_control_ch = i + 1;
14559 return (i);
14560 }
14561 }
14562
14563 return (0);
14564}
14565
14566static void channel_xmit_xon(PLCI *plci) {
14567 DIVA_CAPI_ADAPTER *a = plci->adapter;
14568 byte ch;
14569
14570 if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) {
14571 return;
14572 }
14573 if ((ch = (byte)find_channel_with_pending_x_on(a, plci)) == 0) {
14574 return;
14575 }
14576 a->ch_flow_control[ch] &= ~N_XON_REQ;
14577 a->ch_flow_control[ch] |= N_XON_SENT;
14578
14579 plci->NL.Req = plci->nl_req = (byte)N_XON;
14580 plci->NL.ReqCh = ch;
14581 plci->NL.X = plci->NData;
14582 plci->NL.XNum = 1;
14583 plci->NData[0].P = &plci->RBuffer[0];
14584 plci->NData[0].PLength = 0;
14585
14586 plci->adapter->request(&plci->NL);
14587}
14588
14589static int channel_can_xon(PLCI *plci, byte ch) {
14590 APPL *APPLptr;
14591 DIVA_CAPI_ADAPTER *a;
14592 word NCCIcode;
14593 dword count;
14594 word Num;
14595 word i;
14596
14597 APPLptr = plci->appl;
14598 a = plci->adapter;
14599
14600 if (!APPLptr)
14601 return (0);
14602
14603 NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8);
14604
14605 /* count all buffers within the Application pool */
14606 /* belonging to the same NCCI. XON if a first is */
14607 /* used. */
14608 count = 0;
14609 Num = 0xffff;
14610 for (i = 0; i < APPLptr->MaxBuffer; i++) {
14611 if (NCCIcode == APPLptr->DataNCCI[i]) count++;
14612 if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i;
14613 }
14614 if ((count > 2) || (Num == 0xffff)) {
14615 return (0);
14616 }
14617 return (1);
14618}
14619
14620
14621/*------------------------------------------------------------------*/
14622
14623static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *a, word offset)
14624{
14625 return 1;
14626}
14627
14628
14629
14630/**********************************************************************************/
14631/* function groups the listening applications according to the CIP mask and the */
14632/* Info_Mask. Each group gets just one Connect_Ind. Some application manufacturer */
14633/* are not multi-instance capable, so they start e.g. 30 applications what causes */
14634/* big problems on application level (one call, 30 Connect_Ind, ect). The */
14635/* function must be enabled by setting "a->group_optimization_enabled" from the */
14636/* OS specific part (per adapter). */
14637/**********************************************************************************/
14638static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci)
14639{
14640 word i, j, k, busy, group_found;
14641 dword info_mask_group[MAX_CIP_TYPES];
14642 dword cip_mask_group[MAX_CIP_TYPES];
14643 word appl_number_group_type[MAX_APPL];
14644 PLCI *auxplci;
14645
14646 /* all APPLs within this inc. call are allowed to dial in */
14647 bitmap_fill(plci->group_optimization_mask_table, MAX_APPL);
14648
14649 if (!a->group_optimization_enabled)
14650 {
14651 dbug(1, dprintf("No group optimization"));
14652 return;
14653 }
14654
14655 dbug(1, dprintf("Group optimization = 0x%x...", a->group_optimization_enabled));
14656
14657 for (i = 0; i < MAX_CIP_TYPES; i++)
14658 {
14659 info_mask_group[i] = 0;
14660 cip_mask_group[i] = 0;
14661 }
14662 for (i = 0; i < MAX_APPL; i++)
14663 {
14664 appl_number_group_type[i] = 0;
14665 }
14666 for (i = 0; i < max_appl; i++) /* check if any multi instance capable application is present */
14667 { /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */
14668 if (application[i].Id && (application[i].MaxNCCI) > 1 && (a->CIP_Mask[i]) && (a->group_optimization_enabled == 1))
14669 {
14670 dbug(1, dprintf("Multi-Instance capable, no optimization required"));
14671 return; /* allow good application unfiltered access */
14672 }
14673 }
14674 for (i = 0; i < max_appl; i++) /* Build CIP Groups */
14675 {
14676 if (application[i].Id && a->CIP_Mask[i])
14677 {
14678 for (k = 0, busy = false; k < a->max_plci; k++)
14679 {
14680 if (a->plci[k].Id)
14681 {
14682 auxplci = &a->plci[k];
14683 if (auxplci->appl == &application[i]) {
14684 /* application has a busy PLCI */
14685 busy = true;
14686 dbug(1, dprintf("Appl 0x%x is busy", i + 1));
14687 } else if (test_bit(i, plci->c_ind_mask_table)) {
14688 /* application has an incoming call pending */
14689 busy = true;
14690 dbug(1, dprintf("Appl 0x%x has inc. call pending", i + 1));
14691 }
14692 }
14693 }
14694
14695 for (j = 0, group_found = 0; j <= (MAX_CIP_TYPES) && !busy && !group_found; j++) /* build groups with free applications only */
14696 {
14697 if (j == MAX_CIP_TYPES) /* all groups are in use but group still not found */
14698 { /* the MAX_CIP_TYPES group enables all calls because of field overflow */
14699 appl_number_group_type[i] = MAX_CIP_TYPES;
14700 group_found = true;
14701 dbug(1, dprintf("Field overflow appl 0x%x", i + 1));
14702 }
14703 else if ((info_mask_group[j] == a->CIP_Mask[i]) && (cip_mask_group[j] == a->Info_Mask[i]))
14704 { /* is group already present ? */
14705 appl_number_group_type[i] = j | 0x80; /* store the group number for each application */
14706 group_found = true;
14707 dbug(1, dprintf("Group 0x%x found with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j]));
14708 }
14709 else if (!info_mask_group[j])
14710 { /* establish a new group */
14711 appl_number_group_type[i] = j | 0x80; /* store the group number for each application */
14712 info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group */
14713 cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group */
14714 group_found = true;
14715 dbug(1, dprintf("New Group 0x%x established with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j]));
14716 }
14717 }
14718 }
14719 }
14720
14721 for (i = 0; i < max_appl; i++) /* Build group_optimization_mask_table */
14722 {
14723 if (appl_number_group_type[i]) /* application is free, has listens and is member of a group */
14724 {
14725 if (appl_number_group_type[i] == MAX_CIP_TYPES)
14726 {
14727 dbug(1, dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled", appl_number_group_type[i], i + 1));
14728 }
14729 else
14730 {
14731 dbug(1, dprintf("Group 0x%x, valid appl = 0x%x", appl_number_group_type[i], i + 1));
14732 for (j = i + 1; j < max_appl; j++) /* search other group members and mark them as busy */
14733 {
14734 if (appl_number_group_type[i] == appl_number_group_type[j])
14735 {
14736 dbug(1, dprintf("Appl 0x%x is member of group 0x%x, no call", j + 1, appl_number_group_type[j]));
14737 /* disable call on other group members */
14738 __clear_bit(j, plci->group_optimization_mask_table);
14739 appl_number_group_type[j] = 0; /* remove disabled group member from group list */
14740 }
14741 }
14742 }
14743 }
14744 else /* application should not get a call */
14745 {
14746 __clear_bit(i, plci->group_optimization_mask_table);
14747 }
14748 }
14749
14750}
14751
14752
14753
14754/* OS notifies the driver about a application Capi_Register */
14755word CapiRegister(word id)
14756{
14757 word i, j, appls_found;
14758
14759 PLCI *plci;
14760 DIVA_CAPI_ADAPTER *a;
14761
14762 for (i = 0, appls_found = 0; i < max_appl; i++)
14763 {
14764 if (application[i].Id && (application[i].Id != id))
14765 {
14766 appls_found++; /* an application has been found */
14767 }
14768 }
14769
14770 if (appls_found) return true;
14771 for (i = 0; i < max_adapter; i++) /* scan all adapters... */
14772 {
14773 a = &adapter[i];
14774 if (a->request)
14775 {
14776 if (a->flag_dynamic_l1_down) /* remove adapter from L1 tristate (Huntgroup) */
14777 {
14778 if (!appls_found) /* first application does a capi register */
14779 {
14780 if ((j = get_plci(a))) /* activate L1 of all adapters */
14781 {
14782 plci = &a->plci[j - 1];
14783 plci->command = 0;
14784 add_p(plci, OAD, "\x01\xfd");
14785 add_p(plci, CAI, "\x01\x80");
14786 add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
14787 add_p(plci, SHIFT | 6, NULL);
14788 add_p(plci, SIN, "\x02\x00\x00");
14789 plci->internal_command = START_L1_SIG_ASSIGN_PEND;
14790 sig_req(plci, ASSIGN, DSIG_ID);
14791 add_p(plci, FTY, "\x02\xff\x07"); /* l1 start */
14792 sig_req(plci, SIG_CTRL, 0);
14793 send_req(plci);
14794 }
14795 }
14796 }
14797 }
14798 }
14799 return false;
14800}
14801
14802/*------------------------------------------------------------------*/
14803
14804/* Functions for virtual Switching e.g. Transfer by join, Conference */
14805
14806static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms)
14807{
14808 word i;
14809 /* Format of vswitch_t:
14810 0 byte length
14811 1 byte VSWITCHIE
14812 2 byte VSWITCH_REQ/VSWITCH_IND
14813 3 byte reserved
14814 4 word VSwitchcommand
14815 6 word returnerror
14816 8... Params
14817 */
14818 if (!plci ||
14819 !plci->appl ||
14820 !plci->State ||
14821 plci->Sig.Ind == NCR_FACILITY
14822 )
14823 return;
14824
14825 for (i = 0; i < MAX_MULTI_IE; i++)
14826 {
14827 if (!parms[i][0]) continue;
14828 if (parms[i][0] < 7)
14829 {
14830 parms[i][0] = 0; /* kill it */
14831 continue;
14832 }
14833 dbug(1, dprintf("VSwitchReqInd(%d)", parms[i][4]));
14834 switch (parms[i][4])
14835 {
14836 case VSJOIN:
14837 if (!plci->relatedPTYPLCI ||
14838 (plci->ptyState != S_ECT && plci->relatedPTYPLCI->ptyState != S_ECT))
14839 { /* Error */
14840 break;
14841 }
14842 /* remember all necessary informations */
14843 if (parms[i][0] != 11 || parms[i][8] != 3) /* Length Test */
14844 {
14845 break;
14846 }
14847 if (parms[i][2] == VSWITCH_IND && parms[i][9] == 1)
14848 { /* first indication after ECT-Request on Consultation Call */
14849 plci->vswitchstate = parms[i][9];
14850 parms[i][9] = 2; /* State */
14851 /* now ask first Call to join */
14852 }
14853 else if (parms[i][2] == VSWITCH_REQ && parms[i][9] == 3)
14854 { /* Answer of VSWITCH_REQ from first Call */
14855 plci->vswitchstate = parms[i][9];
14856 /* tell consultation call to join
14857 and the protocol capabilities of the first call */
14858 }
14859 else
14860 { /* Error */
14861 break;
14862 }
14863 plci->vsprot = parms[i][10]; /* protocol */
14864 plci->vsprotdialect = parms[i][11]; /* protocoldialect */
14865 /* send join request to related PLCI */
14866 parms[i][1] = VSWITCHIE;
14867 parms[i][2] = VSWITCH_REQ;
14868
14869 plci->relatedPTYPLCI->command = 0;
14870 plci->relatedPTYPLCI->internal_command = VSWITCH_REQ_PEND;
14871 add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]);
14872 sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
14873 send_req(plci->relatedPTYPLCI);
14874 break;
14875 case VSTRANSPORT:
14876 default:
14877 if (plci->relatedPTYPLCI &&
14878 plci->vswitchstate == 3 &&
14879 plci->relatedPTYPLCI->vswitchstate == 3)
14880 {
14881 add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]);
14882 sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
14883 send_req(plci->relatedPTYPLCI);
14884 }
14885 break;
14886 }
14887 parms[i][0] = 0; /* kill it */
14888 }
14889}
14890
14891
14892/*------------------------------------------------------------------*/
14893
14894static int diva_get_dma_descriptor(PLCI *plci, dword *dma_magic) {
14895 ENTITY e;
14896 IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
14897
14898 if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) {
14899 return (-1);
14900 }
14901
14902 pReq->xdi_dma_descriptor_operation.Req = 0;
14903 pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
14904
14905 pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
14906 pReq->xdi_dma_descriptor_operation.info.descriptor_number = -1;
14907 pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
14908 pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0;
14909
14910 e.user[0] = plci->adapter->Id - 1;
14911 plci->adapter->request((ENTITY *)pReq);
14912
14913 if (!pReq->xdi_dma_descriptor_operation.info.operation &&
14914 (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
14915 pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
14916 *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
14917 dbug(3, dprintf("dma_alloc, a:%d (%d-%08x)",
14918 plci->adapter->Id,
14919 pReq->xdi_dma_descriptor_operation.info.descriptor_number,
14920 *dma_magic));
14921 return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
14922 } else {
14923 dbug(1, dprintf("dma_alloc failed"));
14924 return (-1);
14925 }
14926}
14927
14928static void diva_free_dma_descriptor(PLCI *plci, int nr) {
14929 ENTITY e;
14930 IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
14931
14932 if (nr < 0) {
14933 return;
14934 }
14935
14936 pReq->xdi_dma_descriptor_operation.Req = 0;
14937 pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
14938
14939 pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
14940 pReq->xdi_dma_descriptor_operation.info.descriptor_number = nr;
14941 pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
14942 pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0;
14943
14944 e.user[0] = plci->adapter->Id - 1;
14945 plci->adapter->request((ENTITY *)pReq);
14946
14947 if (!pReq->xdi_dma_descriptor_operation.info.operation) {
14948 dbug(1, dprintf("dma_free(%d)", nr));
14949 } else {
14950 dbug(1, dprintf("dma_free failed (%d)", nr));
14951 }
14952}
14953
14954/*------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/mi_pc.h b/drivers/isdn/hardware/eicon/mi_pc.h
deleted file mode 100644
index 83e9ed8c1bf3..000000000000
--- a/drivers/isdn/hardware/eicon/mi_pc.h
+++ /dev/null
@@ -1,204 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26/*----------------------------------------------------------------------------
27// MAESTRA ISA PnP */
28#define BRI_MEMORY_BASE 0x1f700000
29#define BRI_MEMORY_SIZE 0x00100000 /* 1MB on the BRI */
30#define BRI_SHARED_RAM_SIZE 0x00010000 /* 64k shared RAM */
31#define BRI_RAY_TAYLOR_DSP_CODE_SIZE 0x00020000 /* max 128k DSP-Code (Ray Taylor's code) */
32#define BRI_ORG_MAX_DSP_CODE_SIZE 0x00050000 /* max 320k DSP-Code (Telindus) */
33#define BRI_V90D_MAX_DSP_CODE_SIZE 0x00060000 /* max 384k DSP-Code if V.90D included */
34#define BRI_CACHED_ADDR(x) (((x) & 0x1fffffffL) | 0x80000000L)
35#define BRI_UNCACHED_ADDR(x) (((x) & 0x1fffffffL) | 0xa0000000L)
36#define ADDR 4
37#define ADDRH 6
38#define DATA 0
39#define RESET 7
40#define DEFAULT_ADDRESS 0x240
41#define DEFAULT_IRQ 3
42#define M_PCI_ADDR 0x04 /* MAESTRA BRI PCI */
43#define M_PCI_ADDRH 0x0c /* MAESTRA BRI PCI */
44#define M_PCI_DATA 0x00 /* MAESTRA BRI PCI */
45#define M_PCI_RESET 0x10 /* MAESTRA BRI PCI */
46/*----------------------------------------------------------------------------
47// MAESTRA PRI PCI */
48#define MP_IRQ_RESET 0xc18 /* offset of isr in the CONFIG memory bar */
49#define MP_IRQ_RESET_VAL 0xfe /* value to clear an interrupt */
50#define MP_MEMORY_SIZE 0x00400000 /* 4MB on standard PRI */
51#define MP2_MEMORY_SIZE 0x00800000 /* 8MB on PRI Rev. 2 */
52#define MP_SHARED_RAM_OFFSET 0x00001000 /* offset of shared RAM base in the DRAM memory bar */
53#define MP_SHARED_RAM_SIZE 0x00010000 /* 64k shared RAM */
54#define MP_PROTOCOL_OFFSET (MP_SHARED_RAM_OFFSET + MP_SHARED_RAM_SIZE)
55#define MP_RAY_TAYLOR_DSP_CODE_SIZE 0x00040000 /* max 256k DSP-Code (Ray Taylor's code) */
56#define MP_ORG_MAX_DSP_CODE_SIZE 0x00060000 /* max 384k DSP-Code (Telindus) */
57#define MP_V90D_MAX_DSP_CODE_SIZE 0x00070000 /* max 448k DSP-Code if V.90D included) */
58#define MP_VOIP_MAX_DSP_CODE_SIZE 0x00090000 /* max 576k DSP-Code if voice over IP included */
59#define MP_CACHED_ADDR(x) (((x) & 0x1fffffffL) | 0x80000000L)
60#define MP_UNCACHED_ADDR(x) (((x) & 0x1fffffffL) | 0xa0000000L)
61#define MP_RESET 0x20 /* offset of RESET register in the DEVICES memory bar */
62/* RESET register bits */
63#define _MP_S2M_RESET 0x10 /* active lo */
64#define _MP_LED2 0x08 /* 1 = on */
65#define _MP_LED1 0x04 /* 1 = on */
66#define _MP_DSP_RESET 0x02 /* active lo */
67#define _MP_RISC_RESET 0x81 /* active hi, bit 7 for compatibility with old boards */
68/* CPU exception context structure in MP shared ram after trap */
69typedef struct mp_xcptcontext_s MP_XCPTC;
70struct mp_xcptcontext_s {
71 dword sr;
72 dword cr;
73 dword epc;
74 dword vaddr;
75 dword regs[32];
76 dword mdlo;
77 dword mdhi;
78 dword reseverd;
79 dword xclass;
80};
81/* boot interface structure for PRI */
82struct mp_load {
83 dword volatile cmd;
84 dword volatile addr;
85 dword volatile len;
86 dword volatile err;
87 dword volatile live;
88 dword volatile res1[0x1b];
89 dword volatile TrapId; /* has value 0x999999XX on a CPU trap */
90 dword volatile res2[0x03];
91 MP_XCPTC volatile xcpt; /* contains register dump */
92 dword volatile rest[((0x1020 >> 2) - 6) - 0x1b - 1 - 0x03 - (sizeof(MP_XCPTC) >> 2)];
93 dword volatile signature;
94 dword data[60000]; /* real interface description */
95};
96/*----------------------------------------------------------------------------*/
97/* SERVER 4BRI (Quattro PCI) */
98#define MQ_BOARD_REG_OFFSET 0x800000 /* PC relative On board registers offset */
99#define MQ_BREG_RISC 0x1200 /* RISC Reset ect */
100#define MQ_RISC_COLD_RESET_MASK 0x0001 /* RISC Cold reset */
101#define MQ_RISC_WARM_RESET_MASK 0x0002 /* RISC Warm reset */
102#define MQ_BREG_IRQ_TEST 0x0608 /* Interrupt request, no CPU interaction */
103#define MQ_IRQ_REQ_ON 0x1
104#define MQ_IRQ_REQ_OFF 0x0
105#define MQ_BOARD_DSP_OFFSET 0xa00000 /* PC relative On board DSP regs offset */
106#define MQ_DSP1_ADDR_OFFSET 0x0008 /* Addr register offset DSP 1 subboard 1 */
107#define MQ_DSP2_ADDR_OFFSET 0x0208 /* Addr register offset DSP 2 subboard 1 */
108#define MQ_DSP1_DATA_OFFSET 0x0000 /* Data register offset DSP 1 subboard 1 */
109#define MQ_DSP2_DATA_OFFSET 0x0200 /* Data register offset DSP 2 subboard 1 */
110#define MQ_DSP_JUNK_OFFSET 0x0400 /* DSP Data/Addr regs subboard offset */
111#define MQ_ISAC_DSP_RESET 0x0028 /* ISAC and DSP reset address offset */
112#define MQ_BOARD_ISAC_DSP_RESET 0x800028 /* ISAC and DSP reset address offset */
113#define MQ_INSTANCE_COUNT 4 /* 4BRI consists of four instances */
114#define MQ_MEMORY_SIZE 0x00400000 /* 4MB on standard 4BRI */
115#define MQ_CTRL_SIZE 0x00002000 /* 8K memory mapped registers */
116#define MQ_SHARED_RAM_SIZE 0x00010000 /* 64k shared RAM */
117#define MQ_ORG_MAX_DSP_CODE_SIZE 0x00050000 /* max 320k DSP-Code (Telindus) */
118#define MQ_V90D_MAX_DSP_CODE_SIZE 0x00060000 /* max 384K DSP-Code if V.90D included */
119#define MQ_VOIP_MAX_DSP_CODE_SIZE 0x00028000 /* max 4*160k = 640K DSP-Code if voice over IP included */
120#define MQ_CACHED_ADDR(x) (((x) & 0x1fffffffL) | 0x80000000L)
121#define MQ_UNCACHED_ADDR(x) (((x) & 0x1fffffffL) | 0xa0000000L)
122/*--------------------------------------------------------------------------------------------*/
123/* Additional definitions reflecting the different address map of the SERVER 4BRI V2 */
124#define MQ2_BREG_RISC 0x0200 /* RISC Reset ect */
125#define MQ2_BREG_IRQ_TEST 0x0400 /* Interrupt request, no CPU interaction */
126#define MQ2_BOARD_DSP_OFFSET 0x800000 /* PC relative On board DSP regs offset */
127#define MQ2_DSP1_DATA_OFFSET 0x1800 /* Data register offset DSP 1 subboard 1 */
128#define MQ2_DSP1_ADDR_OFFSET 0x1808 /* Addr register offset DSP 1 subboard 1 */
129#define MQ2_DSP2_DATA_OFFSET 0x1810 /* Data register offset DSP 2 subboard 1 */
130#define MQ2_DSP2_ADDR_OFFSET 0x1818 /* Addr register offset DSP 2 subboard 1 */
131#define MQ2_DSP_JUNK_OFFSET 0x1000 /* DSP Data/Addr regs subboard offset */
132#define MQ2_ISAC_DSP_RESET 0x0000 /* ISAC and DSP reset address offset */
133#define MQ2_BOARD_ISAC_DSP_RESET 0x800000 /* ISAC and DSP reset address offset */
134#define MQ2_IPACX_CONFIG 0x0300 /* IPACX Configuration TE(0)/NT(1) */
135#define MQ2_BOARD_IPACX_CONFIG 0x800300 /* "" */
136#define MQ2_MEMORY_SIZE 0x01000000 /* 16MB code/data memory */
137#define MQ2_CTRL_SIZE 0x00008000 /* 32K memory mapped registers */
138/*----------------------------------------------------------------------------*/
139/* SERVER BRI 2M/2F as derived from 4BRI V2 */
140#define BRI2_MEMORY_SIZE 0x00800000 /* 8MB code/data memory */
141#define BRI2_PROTOCOL_MEMORY_SIZE (MQ2_MEMORY_SIZE >> 2) /* same as one 4BRI Rev.2 task */
142#define BRI2_CTRL_SIZE 0x00008000 /* 32K memory mapped registers */
143#define M_INSTANCE_COUNT 1 /* BRI consists of one instance */
144/*
145 * Some useful constants for proper initialization of the GT6401x
146 */
147#define ID_REG 0x0000 /*Pci reg-contain the Dev&Ven ID of the card*/
148#define RAS0_BASEREG 0x0010 /*Ras0 register - contain the base addr Ras0*/
149#define RAS2_BASEREG 0x0014
150#define CS_BASEREG 0x0018
151#define BOOT_BASEREG 0x001c
152#define GTREGS_BASEREG 0x0024 /*GTRegsBase reg-contain the base addr where*/
153 /*the GT64010 internal regs where mapped */
154/*
155 * GT64010 internal registers
156 */
157/* DRAM device coding */
158#define LOW_RAS0_DREG 0x0400 /*Ras0 low decode address*/
159#define HI_RAS0_DREG 0x0404 /*Ras0 high decode address*/
160#define LOW_RAS1_DREG 0x0408 /*Ras1 low decode address*/
161#define HI_RAS1_DREG 0x040c /*Ras1 high decode address*/
162#define LOW_RAS2_DREG 0x0410 /*Ras2 low decode address*/
163#define HI_RAS2_DREG 0x0414 /*Ras2 high decode address*/
164#define LOW_RAS3_DREG 0x0418 /*Ras3 low decode address*/
165#define HI_RAS3_DREG 0x041c /*Ras3 high decode address*/
166/* I/O CS device coding */
167#define LOW_CS0_DREG 0x0420 /* CS0* low decode register */
168#define HI_CS0_DREG 0x0424 /* CS0* high decode register */
169#define LOW_CS1_DREG 0x0428 /* CS1* low decode register */
170#define HI_CS1_DREG 0x042c /* CS1* high decode register */
171#define LOW_CS2_DREG 0x0430 /* CS2* low decode register */
172#define HI_CS2_DREG 0x0434 /* CS2* high decode register */
173#define LOW_CS3_DREG 0x0438 /* CS3* low decode register */
174#define HI_CS3_DREG 0x043c /* CS3* high decode register */
175/* Boot PROM device coding */
176#define LOW_BOOTCS_DREG 0x0440 /* Boot CS low decode register */
177#define HI_BOOTCS_DREG 0x0444 /* Boot CS High decode register */
178/* DRAM group coding (for CPU) */
179#define LO_RAS10_GREG 0x0008 /*Ras1..0 group low decode address*/
180#define HI_RAS10_GREG 0x0010 /*Ras1..0 group high decode address*/
181#define LO_RAS32_GREG 0x0018 /*Ras3..2 group low decode address */
182#define HI_RAS32_GREG 0x0020 /*Ras3..2 group high decode address */
183/* I/O CS group coding for (CPU) */
184#define LO_CS20_GREG 0x0028 /* CS2..0 group low decode register */
185#define HI_CS20_GREG 0x0030 /* CS2..0 group high decode register */
186#define LO_CS3B_GREG 0x0038 /* CS3 & PROM group low decode register */
187#define HI_CS3B_GREG 0x0040 /* CS3 & PROM group high decode register */
188/* Galileo specific PCI config. */
189#define PCI_TIMEOUT_RET 0x0c04 /* Time Out and retry register */
190#define RAS10_BANKSIZE 0x0c08 /* RAS 1..0 group PCI bank size */
191#define RAS32_BANKSIZE 0x0c0c /* RAS 3..2 group PCI bank size */
192#define CS20_BANKSIZE 0x0c10 /* CS 2..0 group PCI bank size */
193#define CS3B_BANKSIZE 0x0c14 /* CS 3 & Boot group PCI bank size */
194#define DRAM_SIZE 0x0001 /*Dram size in mega bytes*/
195#define PROM_SIZE 0x08000 /*Prom size in bytes*/
196/*--------------------------------------------------------------------------*/
197#define OFFS_DIVA_INIT_TASK_COUNT 0x68
198#define OFFS_DSP_CODE_BASE_ADDR 0x6c
199#define OFFS_XLOG_BUF_ADDR 0x70
200#define OFFS_XLOG_COUNT_ADDR 0x74
201#define OFFS_XLOG_OUT_ADDR 0x78
202#define OFFS_PROTOCOL_END_ADDR 0x7c
203#define OFFS_PROTOCOL_ID_STRING 0x80
204/*--------------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/mntfunc.c b/drivers/isdn/hardware/eicon/mntfunc.c
deleted file mode 100644
index 1cd9affb6058..000000000000
--- a/drivers/isdn/hardware/eicon/mntfunc.c
+++ /dev/null
@@ -1,370 +0,0 @@
1/* $Id: mntfunc.c,v 1.19.6.4 2005/01/31 12:22:20 armin Exp $
2 *
3 * Driver for Eicon DIVA Server ISDN cards.
4 * Maint module
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13
14#include "platform.h"
15#include "di_defs.h"
16#include "divasync.h"
17#include "debug_if.h"
18
19extern char *DRIVERRELEASE_MNT;
20
21#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
22#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
23
24extern void DIVA_DIDD_Read(void *, int);
25
26static dword notify_handle;
27static DESCRIPTOR DAdapter;
28static DESCRIPTOR MAdapter;
29static DESCRIPTOR MaintDescriptor =
30{ IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp };
31
32extern int diva_os_copy_to_user(void *os_handle, void __user *dst,
33 const void *src, int length);
34extern int diva_os_copy_from_user(void *os_handle, void *dst,
35 const void __user *src, int length);
36
37static void no_printf(unsigned char *x, ...)
38{
39 /* dummy debug function */
40}
41
42#include "debuglib.c"
43
44/*
45 * DIDD callback function
46 */
47static void *didd_callback(void *context, DESCRIPTOR *adapter,
48 int removal)
49{
50 if (adapter->type == IDI_DADAPTER) {
51 DBG_ERR(("cb: Change in DAdapter ? Oops ?."));
52 } else if (adapter->type == IDI_DIMAINT) {
53 if (removal) {
54 DbgDeregister();
55 memset(&MAdapter, 0, sizeof(MAdapter));
56 dprintf = no_printf;
57 } else {
58 memcpy(&MAdapter, adapter, sizeof(MAdapter));
59 dprintf = (DIVA_DI_PRINTF) MAdapter.request;
60 DbgRegister("MAINT", DRIVERRELEASE_MNT, DBG_DEFAULT);
61 }
62 } else if ((adapter->type > 0) && (adapter->type < 16)) {
63 if (removal) {
64 diva_mnt_remove_xdi_adapter(adapter);
65 } else {
66 diva_mnt_add_xdi_adapter(adapter);
67 }
68 }
69 return (NULL);
70}
71
72/*
73 * connect to didd
74 */
75static int __init connect_didd(void)
76{
77 int x = 0;
78 int dadapter = 0;
79 IDI_SYNC_REQ req;
80 DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
81
82 DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
83
84 for (x = 0; x < MAX_DESCRIPTORS; x++) {
85 if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */
86 dadapter = 1;
87 memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
88 req.didd_notify.e.Req = 0;
89 req.didd_notify.e.Rc =
90 IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
91 req.didd_notify.info.callback = (void *)didd_callback;
92 req.didd_notify.info.context = NULL;
93 DAdapter.request((ENTITY *)&req);
94 if (req.didd_notify.e.Rc != 0xff)
95 return (0);
96 notify_handle = req.didd_notify.info.handle;
97 /* Register MAINT (me) */
98 req.didd_add_adapter.e.Req = 0;
99 req.didd_add_adapter.e.Rc =
100 IDI_SYNC_REQ_DIDD_ADD_ADAPTER;
101 req.didd_add_adapter.info.descriptor =
102 (void *) &MaintDescriptor;
103 DAdapter.request((ENTITY *)&req);
104 if (req.didd_add_adapter.e.Rc != 0xff)
105 return (0);
106 } else if ((DIDD_Table[x].type > 0)
107 && (DIDD_Table[x].type < 16)) {
108 diva_mnt_add_xdi_adapter(&DIDD_Table[x]);
109 }
110 }
111 return (dadapter);
112}
113
114/*
115 * disconnect from didd
116 */
117static void __exit disconnect_didd(void)
118{
119 IDI_SYNC_REQ req;
120
121 req.didd_notify.e.Req = 0;
122 req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
123 req.didd_notify.info.handle = notify_handle;
124 DAdapter.request((ENTITY *)&req);
125
126 req.didd_remove_adapter.e.Req = 0;
127 req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER;
128 req.didd_remove_adapter.info.p_request =
129 (IDI_CALL) MaintDescriptor.request;
130 DAdapter.request((ENTITY *)&req);
131}
132
133/*
134 * read/write maint
135 */
136int maint_read_write(void __user *buf, int count)
137{
138 byte data[128];
139 dword cmd, id, mask;
140 int ret = 0;
141
142 if (count < (3 * sizeof(dword)))
143 return (-EFAULT);
144
145 if (diva_os_copy_from_user(NULL, (void *) &data[0],
146 buf, 3 * sizeof(dword))) {
147 return (-EFAULT);
148 }
149
150 cmd = *(dword *)&data[0]; /* command */
151 id = *(dword *)&data[4]; /* driver id */
152 mask = *(dword *)&data[8]; /* mask or size */
153
154 switch (cmd) {
155 case DITRACE_CMD_GET_DRIVER_INFO:
156 if ((ret = diva_get_driver_info(id, data, sizeof(data))) > 0) {
157 if ((count < ret) || diva_os_copy_to_user
158 (NULL, buf, (void *) &data[0], ret))
159 ret = -EFAULT;
160 } else {
161 ret = -EINVAL;
162 }
163 break;
164
165 case DITRACE_READ_DRIVER_DBG_MASK:
166 if ((ret = diva_get_driver_dbg_mask(id, (byte *) data)) > 0) {
167 if ((count < ret) || diva_os_copy_to_user
168 (NULL, buf, (void *) &data[0], ret))
169 ret = -EFAULT;
170 } else {
171 ret = -ENODEV;
172 }
173 break;
174
175 case DITRACE_WRITE_DRIVER_DBG_MASK:
176 if ((ret = diva_set_driver_dbg_mask(id, mask)) <= 0) {
177 ret = -ENODEV;
178 }
179 break;
180
181 /*
182 Filter commands will ignore the ID due to fact that filtering affects
183 the B- channel and Audio Tap trace levels only. Also MAINT driver will
184 select the right trace ID by itself
185 */
186 case DITRACE_WRITE_SELECTIVE_TRACE_FILTER:
187 if (!mask) {
188 ret = diva_set_trace_filter(1, "*");
189 } else if (mask < sizeof(data)) {
190 if (diva_os_copy_from_user(NULL, data, (char __user *)buf + 12, mask)) {
191 ret = -EFAULT;
192 } else {
193 ret = diva_set_trace_filter((int)mask, data);
194 }
195 } else {
196 ret = -EINVAL;
197 }
198 break;
199
200 case DITRACE_READ_SELECTIVE_TRACE_FILTER:
201 if ((ret = diva_get_trace_filter(sizeof(data), data)) > 0) {
202 if (diva_os_copy_to_user(NULL, buf, data, ret))
203 ret = -EFAULT;
204 } else {
205 ret = -ENODEV;
206 }
207 break;
208
209 case DITRACE_READ_TRACE_ENTRY:{
210 diva_os_spin_lock_magic_t old_irql;
211 word size;
212 diva_dbg_entry_head_t *pmsg;
213 byte *pbuf;
214
215 if (!(pbuf = diva_os_malloc(0, mask))) {
216 return (-ENOMEM);
217 }
218
219 for (;;) {
220 if (!(pmsg =
221 diva_maint_get_message(&size, &old_irql))) {
222 break;
223 }
224 if (size > mask) {
225 diva_maint_ack_message(0, &old_irql);
226 ret = -EINVAL;
227 break;
228 }
229 ret = size;
230 memcpy(pbuf, pmsg, size);
231 diva_maint_ack_message(1, &old_irql);
232 if ((count < size) ||
233 diva_os_copy_to_user(NULL, buf, (void *) pbuf, size))
234 ret = -EFAULT;
235 break;
236 }
237 diva_os_free(0, pbuf);
238 }
239 break;
240
241 case DITRACE_READ_TRACE_ENTRYS:{
242 diva_os_spin_lock_magic_t old_irql;
243 word size;
244 diva_dbg_entry_head_t *pmsg;
245 byte *pbuf = NULL;
246 int written = 0;
247
248 if (mask < 4096) {
249 ret = -EINVAL;
250 break;
251 }
252 if (!(pbuf = diva_os_malloc(0, mask))) {
253 return (-ENOMEM);
254 }
255
256 for (;;) {
257 if (!(pmsg =
258 diva_maint_get_message(&size, &old_irql))) {
259 break;
260 }
261 if ((size + 8) > mask) {
262 diva_maint_ack_message(0, &old_irql);
263 break;
264 }
265 /*
266 Write entry length
267 */
268 pbuf[written++] = (byte) size;
269 pbuf[written++] = (byte) (size >> 8);
270 pbuf[written++] = 0;
271 pbuf[written++] = 0;
272 /*
273 Write message
274 */
275 memcpy(&pbuf[written], pmsg, size);
276 diva_maint_ack_message(1, &old_irql);
277 written += size;
278 mask -= (size + 4);
279 }
280 pbuf[written++] = 0;
281 pbuf[written++] = 0;
282 pbuf[written++] = 0;
283 pbuf[written++] = 0;
284
285 if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) {
286 ret = -EFAULT;
287 } else {
288 ret = written;
289 }
290 diva_os_free(0, pbuf);
291 }
292 break;
293
294 default:
295 ret = -EINVAL;
296 }
297 return (ret);
298}
299
300/*
301 * init
302 */
303int __init mntfunc_init(int *buffer_length, void **buffer,
304 unsigned long diva_dbg_mem)
305{
306 if (*buffer_length < 64) {
307 *buffer_length = 64;
308 }
309 if (*buffer_length > 512) {
310 *buffer_length = 512;
311 }
312 *buffer_length *= 1024;
313
314 if (diva_dbg_mem) {
315 *buffer = (void *) diva_dbg_mem;
316 } else {
317 while ((*buffer_length >= (64 * 1024))
318 &&
319 (!(*buffer = diva_os_malloc(0, *buffer_length)))) {
320 *buffer_length -= 1024;
321 }
322
323 if (!*buffer) {
324 DBG_ERR(("init: Can not alloc trace buffer"));
325 return (0);
326 }
327 }
328
329 if (diva_maint_init(*buffer, *buffer_length, (diva_dbg_mem == 0))) {
330 if (!diva_dbg_mem) {
331 diva_os_free(0, *buffer);
332 }
333 DBG_ERR(("init: maint init failed"));
334 return (0);
335 }
336
337 if (!connect_didd()) {
338 DBG_ERR(("init: failed to connect to DIDD."));
339 diva_maint_finit();
340 if (!diva_dbg_mem) {
341 diva_os_free(0, *buffer);
342 }
343 return (0);
344 }
345 return (1);
346}
347
348/*
349 * exit
350 */
351void __exit mntfunc_finit(void)
352{
353 void *buffer;
354 int i = 100;
355
356 DbgDeregister();
357
358 while (diva_mnt_shutdown_xdi_adapters() && i--) {
359 diva_os_sleep(10);
360 }
361
362 disconnect_didd();
363
364 if ((buffer = diva_maint_finit())) {
365 diva_os_free(0, buffer);
366 }
367
368 memset(&MAdapter, 0, sizeof(MAdapter));
369 dprintf = no_printf;
370}
diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
deleted file mode 100644
index 87db5f4df27d..000000000000
--- a/drivers/isdn/hardware/eicon/os_4bri.c
+++ /dev/null
@@ -1,1132 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 armin Exp $ */
3
4#include "platform.h"
5#include "debuglib.h"
6#include "cardtype.h"
7#include "pc.h"
8#include "pr_pc.h"
9#include "di_defs.h"
10#include "dsp_defs.h"
11#include "di.h"
12#include "io.h"
13
14#include "xdi_msg.h"
15#include "xdi_adapter.h"
16#include "os_4bri.h"
17#include "diva_pci.h"
18#include "mi_pc.h"
19#include "dsrv4bri.h"
20#include "helpers.h"
21
22static void *diva_xdiLoadFileFile = NULL;
23static dword diva_xdiLoadFileLength = 0;
24
25/*
26** IMPORTS
27*/
28extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter);
29extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter);
30extern void diva_xdi_display_adapter_features(int card);
31extern void diva_add_slave_adapter(diva_os_xdi_adapter_t *a);
32
33extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter);
34extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter);
35
36extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
37
38/*
39** LOCALS
40*/
41static unsigned long _4bri_bar_length[4] = {
42 0x100,
43 0x100, /* I/O */
44 MQ_MEMORY_SIZE,
45 0x2000
46};
47static unsigned long _4bri_v2_bar_length[4] = {
48 0x100,
49 0x100, /* I/O */
50 MQ2_MEMORY_SIZE,
51 0x10000
52};
53static unsigned long _4bri_v2_bri_bar_length[4] = {
54 0x100,
55 0x100, /* I/O */
56 BRI2_MEMORY_SIZE,
57 0x10000
58};
59
60
61static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
62static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a);
63static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
64 diva_xdi_um_cfg_cmd_t *cmd,
65 int length);
66static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a);
67static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a,
68 byte *data, dword length);
69static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter);
70static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
71 dword address,
72 const byte *data,
73 dword length, dword limit);
74static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
75 dword start_address, dword features);
76static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter);
77static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a);
78
79static int _4bri_is_rev_2_card(int card_ordinal)
80{
81 switch (card_ordinal) {
82 case CARDTYPE_DIVASRV_Q_8M_V2_PCI:
83 case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI:
84 case CARDTYPE_DIVASRV_B_2M_V2_PCI:
85 case CARDTYPE_DIVASRV_B_2F_PCI:
86 case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
87 return (1);
88 }
89 return (0);
90}
91
92static int _4bri_is_rev_2_bri_card(int card_ordinal)
93{
94 switch (card_ordinal) {
95 case CARDTYPE_DIVASRV_B_2M_V2_PCI:
96 case CARDTYPE_DIVASRV_B_2F_PCI:
97 case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
98 return (1);
99 }
100 return (0);
101}
102
103static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
104{
105 dword offset = a->resources.pci.qoffset;
106 dword c_offset = offset * a->xdi_adapter.ControllerNumber;
107
108 a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 2;
109 a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
110 a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
111 a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 0;
112 a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 3;
113 a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;
114
115 /*
116 Set up hardware related pointers
117 */
118 a->xdi_adapter.Address = a->resources.pci.addr[2]; /* BAR2 SDRAM */
119 a->xdi_adapter.Address += c_offset;
120
121 a->xdi_adapter.Control = a->resources.pci.addr[2]; /* BAR2 SDRAM */
122
123 a->xdi_adapter.ram = a->resources.pci.addr[2]; /* BAR2 SDRAM */
124 a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
125
126 a->xdi_adapter.reset = a->resources.pci.addr[0]; /* BAR0 CONFIG */
127 /*
128 ctlReg contains the register address for the MIPS CPU reset control
129 */
130 a->xdi_adapter.ctlReg = a->resources.pci.addr[3]; /* BAR3 CNTRL */
131 /*
132 prom contains the register address for FPGA and EEPROM programming
133 */
134 a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
135}
136
137/*
138** BAR0 - MEM - 0x100 - CONFIG MEM
139** BAR1 - I/O - 0x100 - UNUSED
140** BAR2 - MEM - MQ_MEMORY_SIZE (MQ2_MEMORY_SIZE on Rev.2) - SDRAM
141** BAR3 - MEM - 0x2000 (0x10000 on Rev.2) - CNTRL
142**
143** Called by master adapter, that will initialize and add slave adapters
144*/
145int diva_4bri_init_card(diva_os_xdi_adapter_t *a)
146{
147 int bar, i;
148 byte __iomem *p;
149 PADAPTER_LIST_ENTRY quadro_list;
150 diva_os_xdi_adapter_t *diva_current;
151 diva_os_xdi_adapter_t *adapter_list[4];
152 PISDN_ADAPTER Slave;
153 unsigned long bar_length[ARRAY_SIZE(_4bri_bar_length)];
154 int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
155 int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT;
156 int factor = (tasks == 1) ? 1 : 2;
157
158 if (v2) {
159 if (_4bri_is_rev_2_bri_card(a->CardOrdinal)) {
160 memcpy(bar_length, _4bri_v2_bri_bar_length,
161 sizeof(bar_length));
162 } else {
163 memcpy(bar_length, _4bri_v2_bar_length,
164 sizeof(bar_length));
165 }
166 } else {
167 memcpy(bar_length, _4bri_bar_length, sizeof(bar_length));
168 }
169 DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
170 bar_length[2], tasks, factor))
171
172 /*
173 Get Serial Number
174 The serial number of 4BRI is accessible in accordance with PCI spec
175 via command register located in configuration space, also we do not
176 have to map any BAR before we can access it
177 */
178 if (!_4bri_get_serial_number(a)) {
179 DBG_ERR(("A: 4BRI can't get Serial Number"))
180 diva_4bri_cleanup_adapter(a);
181 return (-1);
182 }
183
184 /*
185 Set properties
186 */
187 a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
188 DBG_LOG(("Load %s, SN:%ld, bus:%02x, func:%02x",
189 a->xdi_adapter.Properties.Name,
190 a->xdi_adapter.serialNo,
191 a->resources.pci.bus, a->resources.pci.func))
192
193 /*
194 First initialization step: get and check hardware resoures.
195 Do not map resources and do not access card at this step
196 */
197 for (bar = 0; bar < 4; bar++) {
198 a->resources.pci.bar[bar] =
199 divasa_get_pci_bar(a->resources.pci.bus,
200 a->resources.pci.func, bar,
201 a->resources.pci.hdev);
202 if (!a->resources.pci.bar[bar]
203 || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
204 DBG_ERR(
205 ("A: invalid bar[%d]=%08x", bar,
206 a->resources.pci.bar[bar]))
207 return (-1);
208 }
209 }
210 a->resources.pci.irq =
211 (byte) divasa_get_pci_irq(a->resources.pci.bus,
212 a->resources.pci.func,
213 a->resources.pci.hdev);
214 if (!a->resources.pci.irq) {
215 DBG_ERR(("A: invalid irq"));
216 return (-1);
217 }
218
219 a->xdi_adapter.sdram_bar = a->resources.pci.bar[2];
220
221 /*
222 Map all MEMORY BAR's
223 */
224 for (bar = 0; bar < 4; bar++) {
225 if (bar != 1) { /* ignore I/O */
226 a->resources.pci.addr[bar] =
227 divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
228 bar_length[bar]);
229 if (!a->resources.pci.addr[bar]) {
230 DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
231 diva_4bri_cleanup_adapter(a);
232 return (-1);
233 }
234 }
235 }
236
237 /*
238 Register I/O port
239 */
240 sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
241
242 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
243 bar_length[1], &a->port_name[0], 1)) {
244 DBG_ERR(("A: 4BRI: can't register bar[1]"))
245 diva_4bri_cleanup_adapter(a);
246 return (-1);
247 }
248
249 a->resources.pci.addr[1] =
250 (void *) (unsigned long) a->resources.pci.bar[1];
251
252 /*
253 Set cleanup pointer for base adapter only, so slave adapter
254 will be unable to get cleanup
255 */
256 a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter;
257
258 /*
259 Create slave adapters
260 */
261 if (tasks > 1) {
262 if (!(a->slave_adapters[0] =
263 (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
264 {
265 diva_4bri_cleanup_adapter(a);
266 return (-1);
267 }
268 if (!(a->slave_adapters[1] =
269 (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
270 {
271 diva_os_free(0, a->slave_adapters[0]);
272 a->slave_adapters[0] = NULL;
273 diva_4bri_cleanup_adapter(a);
274 return (-1);
275 }
276 if (!(a->slave_adapters[2] =
277 (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
278 {
279 diva_os_free(0, a->slave_adapters[0]);
280 diva_os_free(0, a->slave_adapters[1]);
281 a->slave_adapters[0] = NULL;
282 a->slave_adapters[1] = NULL;
283 diva_4bri_cleanup_adapter(a);
284 return (-1);
285 }
286 memset(a->slave_adapters[0], 0x00, sizeof(*a));
287 memset(a->slave_adapters[1], 0x00, sizeof(*a));
288 memset(a->slave_adapters[2], 0x00, sizeof(*a));
289 }
290
291 adapter_list[0] = a;
292 adapter_list[1] = a->slave_adapters[0];
293 adapter_list[2] = a->slave_adapters[1];
294 adapter_list[3] = a->slave_adapters[2];
295
296 /*
297 Allocate slave list
298 */
299 quadro_list =
300 (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
301 if (!(a->slave_list = quadro_list)) {
302 for (i = 0; i < (tasks - 1); i++) {
303 diva_os_free(0, a->slave_adapters[i]);
304 a->slave_adapters[i] = NULL;
305 }
306 diva_4bri_cleanup_adapter(a);
307 return (-1);
308 }
309 memset(quadro_list, 0x00, sizeof(*quadro_list));
310
311 /*
312 Set interfaces
313 */
314 a->xdi_adapter.QuadroList = quadro_list;
315 for (i = 0; i < tasks; i++) {
316 adapter_list[i]->xdi_adapter.ControllerNumber = i;
317 adapter_list[i]->xdi_adapter.tasks = tasks;
318 quadro_list->QuadroAdapter[i] =
319 &adapter_list[i]->xdi_adapter;
320 }
321
322 for (i = 0; i < tasks; i++) {
323 diva_current = adapter_list[i];
324
325 diva_current->dsp_mask = 0x00000003;
326
327 diva_current->xdi_adapter.a.io =
328 &diva_current->xdi_adapter;
329 diva_current->xdi_adapter.DIRequest = request;
330 diva_current->interface.cmd_proc = diva_4bri_cmd_card_proc;
331 diva_current->xdi_adapter.Properties =
332 CardProperties[a->CardOrdinal];
333 diva_current->CardOrdinal = a->CardOrdinal;
334
335 diva_current->xdi_adapter.Channels =
336 CardProperties[a->CardOrdinal].Channels;
337 diva_current->xdi_adapter.e_max =
338 CardProperties[a->CardOrdinal].E_info;
339 diva_current->xdi_adapter.e_tbl =
340 diva_os_malloc(0,
341 diva_current->xdi_adapter.e_max *
342 sizeof(E_INFO));
343
344 if (!diva_current->xdi_adapter.e_tbl) {
345 diva_4bri_cleanup_slave_adapters(a);
346 diva_4bri_cleanup_adapter(a);
347 for (i = 1; i < (tasks - 1); i++) {
348 diva_os_free(0, adapter_list[i]);
349 }
350 return (-1);
351 }
352 memset(diva_current->xdi_adapter.e_tbl, 0x00,
353 diva_current->xdi_adapter.e_max * sizeof(E_INFO));
354
355 if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.isr_spin_lock, "isr")) {
356 diva_4bri_cleanup_slave_adapters(a);
357 diva_4bri_cleanup_adapter(a);
358 for (i = 1; i < (tasks - 1); i++) {
359 diva_os_free(0, adapter_list[i]);
360 }
361 return (-1);
362 }
363 if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.data_spin_lock, "data")) {
364 diva_4bri_cleanup_slave_adapters(a);
365 diva_4bri_cleanup_adapter(a);
366 for (i = 1; i < (tasks - 1); i++) {
367 diva_os_free(0, adapter_list[i]);
368 }
369 return (-1);
370 }
371
372 strcpy(diva_current->xdi_adapter.req_soft_isr. dpc_thread_name, "kdivas4brid");
373
374 if (diva_os_initialize_soft_isr(&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine,
375 &diva_current->xdi_adapter)) {
376 diva_4bri_cleanup_slave_adapters(a);
377 diva_4bri_cleanup_adapter(a);
378 for (i = 1; i < (tasks - 1); i++) {
379 diva_os_free(0, adapter_list[i]);
380 }
381 return (-1);
382 }
383
384 /*
385 Do not initialize second DPC - only one thread will be created
386 */
387 diva_current->xdi_adapter.isr_soft_isr.object =
388 diva_current->xdi_adapter.req_soft_isr.object;
389 }
390
391 if (v2) {
392 prepare_qBri2_functions(&a->xdi_adapter);
393 } else {
394 prepare_qBri_functions(&a->xdi_adapter);
395 }
396
397 for (i = 0; i < tasks; i++) {
398 diva_current = adapter_list[i];
399 if (i)
400 memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
401 diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor);
402 }
403
404 /*
405 Set up hardware related pointers
406 */
407 a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0]; /* BAR0 CONFIG */
408 a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1]; /* BAR1 */
409 a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3]; /* BAR3 CNTRL */
410
411 for (i = 0; i < tasks; i++) {
412 diva_current = adapter_list[i];
413 diva_4bri_set_addresses(diva_current);
414 Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
415 Slave->MultiMaster = &a->xdi_adapter;
416 Slave->sdram_bar = a->xdi_adapter.sdram_bar;
417 if (i) {
418 Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
419 a->xdi_adapter.serialNo;
420 Slave->cardType = a->xdi_adapter.cardType;
421 }
422 }
423
424 /*
425 reset contains the base address for the PLX 9054 register set
426 */
427 p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
428 WRITE_BYTE(&p[PLX9054_INTCSR], 0x00); /* disable PCI interrupts */
429 DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
430
431 /*
432 Set IRQ handler
433 */
434 a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
435 sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA 4BRI %ld",
436 (long) a->xdi_adapter.serialNo);
437
438 if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
439 a->xdi_adapter.irq_info.irq_name)) {
440 diva_4bri_cleanup_slave_adapters(a);
441 diva_4bri_cleanup_adapter(a);
442 for (i = 1; i < (tasks - 1); i++) {
443 diva_os_free(0, adapter_list[i]);
444 }
445 return (-1);
446 }
447
448 a->xdi_adapter.irq_info.registered = 1;
449
450 /*
451 Add three slave adapters
452 */
453 if (tasks > 1) {
454 diva_add_slave_adapter(adapter_list[1]);
455 diva_add_slave_adapter(adapter_list[2]);
456 diva_add_slave_adapter(adapter_list[3]);
457 }
458
459 diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
460 a->resources.pci.irq, a->xdi_adapter.serialNo);
461
462 return (0);
463}
464
465/*
466** Cleanup function will be called for master adapter only
467** this is guaranteed by design: cleanup callback is set
468** by master adapter only
469*/
470static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
471{
472 int bar;
473
474 /*
475 Stop adapter if running
476 */
477 if (a->xdi_adapter.Initialized) {
478 diva_4bri_stop_adapter(a);
479 }
480
481 /*
482 Remove IRQ handler
483 */
484 if (a->xdi_adapter.irq_info.registered) {
485 diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
486 }
487 a->xdi_adapter.irq_info.registered = 0;
488
489 /*
490 Free DPC's and spin locks on all adapters
491 */
492 diva_4bri_cleanup_slave_adapters(a);
493
494 /*
495 Unmap all BARS
496 */
497 for (bar = 0; bar < 4; bar++) {
498 if (bar != 1) {
499 if (a->resources.pci.bar[bar]
500 && a->resources.pci.addr[bar]) {
501 divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
502 a->resources.pci.bar[bar] = 0;
503 a->resources.pci.addr[bar] = NULL;
504 }
505 }
506 }
507
508 /*
509 Unregister I/O
510 */
511 if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
512 diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
513 _4bri_is_rev_2_card(a->
514 CardOrdinal) ?
515 _4bri_v2_bar_length[1] :
516 _4bri_bar_length[1],
517 &a->port_name[0], 1);
518 a->resources.pci.bar[1] = 0;
519 a->resources.pci.addr[1] = NULL;
520 }
521
522 if (a->slave_list) {
523 diva_os_free(0, a->slave_list);
524 a->slave_list = NULL;
525 }
526
527 return (0);
528}
529
530static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a)
531{
532 dword data[64];
533 dword serNo;
534 word addr, status, i, j;
535 byte Bus, Slot;
536 void *hdev;
537
538 Bus = a->resources.pci.bus;
539 Slot = a->resources.pci.func;
540 hdev = a->resources.pci.hdev;
541
542 for (i = 0; i < 64; ++i) {
543 addr = i * 4;
544 for (j = 0; j < 5; ++j) {
545 PCIwrite(Bus, Slot, 0x4E, &addr, sizeof(addr),
546 hdev);
547 diva_os_wait(1);
548 PCIread(Bus, Slot, 0x4E, &status, sizeof(status),
549 hdev);
550 if (status & 0x8000)
551 break;
552 }
553 if (j >= 5) {
554 DBG_ERR(("EEPROM[%d] read failed (0x%x)", i * 4, addr))
555 return (0);
556 }
557 PCIread(Bus, Slot, 0x50, &data[i], sizeof(data[i]), hdev);
558 }
559 DBG_BLK(((char *) &data[0], sizeof(data)))
560
561 serNo = data[32];
562 if (serNo == 0 || serNo == 0xffffffff)
563 serNo = data[63];
564
565 if (!serNo) {
566 DBG_LOG(("W: Serial Number == 0, create one serial number"));
567 serNo = a->resources.pci.bar[1] & 0xffff0000;
568 serNo |= a->resources.pci.bus << 8;
569 serNo |= a->resources.pci.func;
570 }
571
572 a->xdi_adapter.serialNo = serNo;
573
574 DBG_REG(("Serial No. : %ld", a->xdi_adapter.serialNo))
575
576 return (serNo);
577}
578
579/*
580** Release resources of slave adapters
581*/
582static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a)
583{
584 diva_os_xdi_adapter_t *adapter_list[4];
585 diva_os_xdi_adapter_t *diva_current;
586 int i;
587
588 adapter_list[0] = a;
589 adapter_list[1] = a->slave_adapters[0];
590 adapter_list[2] = a->slave_adapters[1];
591 adapter_list[3] = a->slave_adapters[2];
592
593 for (i = 0; i < a->xdi_adapter.tasks; i++) {
594 diva_current = adapter_list[i];
595 if (diva_current) {
596 diva_os_destroy_spin_lock(&diva_current->
597 xdi_adapter.
598 isr_spin_lock, "unload");
599 diva_os_destroy_spin_lock(&diva_current->
600 xdi_adapter.
601 data_spin_lock,
602 "unload");
603
604 diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
605 req_soft_isr);
606 diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
607 isr_soft_isr);
608
609 diva_os_remove_soft_isr(&diva_current->xdi_adapter.
610 req_soft_isr);
611 diva_current->xdi_adapter.isr_soft_isr.object = NULL;
612
613 if (diva_current->xdi_adapter.e_tbl) {
614 diva_os_free(0,
615 diva_current->xdi_adapter.
616 e_tbl);
617 }
618 diva_current->xdi_adapter.e_tbl = NULL;
619 diva_current->xdi_adapter.e_max = 0;
620 diva_current->xdi_adapter.e_count = 0;
621 }
622 }
623
624 return (0);
625}
626
627static int
628diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
629 diva_xdi_um_cfg_cmd_t *cmd, int length)
630{
631 int ret = -1;
632
633 if (cmd->adapter != a->controller) {
634 DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
635 cmd->adapter, a->controller))
636 return (-1);
637 }
638
639 switch (cmd->command) {
640 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
641 a->xdi_mbox.data_length = sizeof(dword);
642 a->xdi_mbox.data =
643 diva_os_malloc(0, a->xdi_mbox.data_length);
644 if (a->xdi_mbox.data) {
645 *(dword *) a->xdi_mbox.data =
646 (dword) a->CardOrdinal;
647 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
648 ret = 0;
649 }
650 break;
651
652 case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
653 a->xdi_mbox.data_length = sizeof(dword);
654 a->xdi_mbox.data =
655 diva_os_malloc(0, a->xdi_mbox.data_length);
656 if (a->xdi_mbox.data) {
657 *(dword *) a->xdi_mbox.data =
658 (dword) a->xdi_adapter.serialNo;
659 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
660 ret = 0;
661 }
662 break;
663
664 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
665 if (!a->xdi_adapter.ControllerNumber) {
666 /*
667 Only master adapter can access hardware config
668 */
669 a->xdi_mbox.data_length = sizeof(dword) * 9;
670 a->xdi_mbox.data =
671 diva_os_malloc(0, a->xdi_mbox.data_length);
672 if (a->xdi_mbox.data) {
673 int i;
674 dword *data = (dword *) a->xdi_mbox.data;
675
676 for (i = 0; i < 8; i++) {
677 *data++ = a->resources.pci.bar[i];
678 }
679 *data++ = (dword) a->resources.pci.irq;
680 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
681 ret = 0;
682 }
683 }
684 break;
685
686 case DIVA_XDI_UM_CMD_GET_CARD_STATE:
687 if (!a->xdi_adapter.ControllerNumber) {
688 a->xdi_mbox.data_length = sizeof(dword);
689 a->xdi_mbox.data =
690 diva_os_malloc(0, a->xdi_mbox.data_length);
691 if (a->xdi_mbox.data) {
692 dword *data = (dword *) a->xdi_mbox.data;
693 if (!a->xdi_adapter.ram
694 || !a->xdi_adapter.reset
695 || !a->xdi_adapter.cfg) {
696 *data = 3;
697 } else if (a->xdi_adapter.trapped) {
698 *data = 2;
699 } else if (a->xdi_adapter.Initialized) {
700 *data = 1;
701 } else {
702 *data = 0;
703 }
704 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
705 ret = 0;
706 }
707 }
708 break;
709
710 case DIVA_XDI_UM_CMD_WRITE_FPGA:
711 if (!a->xdi_adapter.ControllerNumber) {
712 ret =
713 diva_4bri_write_fpga_image(a,
714 (byte *)&cmd[1],
715 cmd->command_data.
716 write_fpga.
717 image_length);
718 }
719 break;
720
721 case DIVA_XDI_UM_CMD_RESET_ADAPTER:
722 if (!a->xdi_adapter.ControllerNumber) {
723 ret = diva_4bri_reset_adapter(&a->xdi_adapter);
724 }
725 break;
726
727 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
728 if (!a->xdi_adapter.ControllerNumber) {
729 ret = diva_4bri_write_sdram_block(&a->xdi_adapter,
730 cmd->
731 command_data.
732 write_sdram.
733 offset,
734 (byte *) &
735 cmd[1],
736 cmd->
737 command_data.
738 write_sdram.
739 length,
740 a->xdi_adapter.
741 MemorySize);
742 }
743 break;
744
745 case DIVA_XDI_UM_CMD_START_ADAPTER:
746 if (!a->xdi_adapter.ControllerNumber) {
747 ret = diva_4bri_start_adapter(&a->xdi_adapter,
748 cmd->command_data.
749 start.offset,
750 cmd->command_data.
751 start.features);
752 }
753 break;
754
755 case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
756 if (!a->xdi_adapter.ControllerNumber) {
757 a->xdi_adapter.features =
758 cmd->command_data.features.features;
759 a->xdi_adapter.a.protocol_capabilities =
760 a->xdi_adapter.features;
761 DBG_TRC(("Set raw protocol features (%08x)",
762 a->xdi_adapter.features))
763 ret = 0;
764 }
765 break;
766
767 case DIVA_XDI_UM_CMD_STOP_ADAPTER:
768 if (!a->xdi_adapter.ControllerNumber) {
769 ret = diva_4bri_stop_adapter(a);
770 }
771 break;
772
773 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
774 ret = diva_card_read_xlog(a);
775 break;
776
777 case DIVA_XDI_UM_CMD_READ_SDRAM:
778 if (!a->xdi_adapter.ControllerNumber
779 && a->xdi_adapter.Address) {
780 if (
781 (a->xdi_mbox.data_length =
782 cmd->command_data.read_sdram.length)) {
783 if (
784 (a->xdi_mbox.data_length +
785 cmd->command_data.read_sdram.offset) <
786 a->xdi_adapter.MemorySize) {
787 a->xdi_mbox.data =
788 diva_os_malloc(0,
789 a->xdi_mbox.
790 data_length);
791 if (a->xdi_mbox.data) {
792 byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
793 byte __iomem *src = p;
794 byte *dst = a->xdi_mbox.data;
795 dword len = a->xdi_mbox.data_length;
796
797 src += cmd->command_data.read_sdram.offset;
798
799 while (len--) {
800 *dst++ = READ_BYTE(src++);
801 }
802 DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
803 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
804 ret = 0;
805 }
806 }
807 }
808 }
809 break;
810
811 default:
812 DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
813 cmd->command))
814 }
815
816 return (ret);
817}
818
819void *xdiLoadFile(char *FileName, dword *FileLength,
820 unsigned long lim)
821{
822 void *ret = diva_xdiLoadFileFile;
823
824 if (FileLength) {
825 *FileLength = diva_xdiLoadFileLength;
826 }
827 diva_xdiLoadFileFile = NULL;
828 diva_xdiLoadFileLength = 0;
829
830 return (ret);
831}
832
833void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)
834{
835}
836
837void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
838{
839}
840
841static int
842diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a, byte *data,
843 dword length)
844{
845 int ret;
846
847 diva_xdiLoadFileFile = data;
848 diva_xdiLoadFileLength = length;
849
850 ret = qBri_FPGA_download(&a->xdi_adapter);
851
852 diva_xdiLoadFileFile = NULL;
853 diva_xdiLoadFileLength = 0;
854
855 return (ret ? 0 : -1);
856}
857
858static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)
859{
860 PISDN_ADAPTER Slave;
861 int i;
862
863 if (!IoAdapter->Address || !IoAdapter->reset) {
864 return (-1);
865 }
866 if (IoAdapter->Initialized) {
867 DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
868 IoAdapter->ANum))
869 return (-1);
870 }
871
872 /*
873 Forget all entities on all adapters
874 */
875 for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) {
876 Slave = IoAdapter->QuadroList->QuadroAdapter[i];
877 Slave->e_count = 0;
878 if (Slave->e_tbl) {
879 memset(Slave->e_tbl, 0x00,
880 Slave->e_max * sizeof(E_INFO));
881 }
882 Slave->head = 0;
883 Slave->tail = 0;
884 Slave->assign = 0;
885 Slave->trapped = 0;
886
887 memset(&Slave->a.IdTable[0], 0x00,
888 sizeof(Slave->a.IdTable));
889 memset(&Slave->a.IdTypeTable[0], 0x00,
890 sizeof(Slave->a.IdTypeTable));
891 memset(&Slave->a.FlowControlIdTable[0], 0x00,
892 sizeof(Slave->a.FlowControlIdTable));
893 memset(&Slave->a.FlowControlSkipTable[0], 0x00,
894 sizeof(Slave->a.FlowControlSkipTable));
895 memset(&Slave->a.misc_flags_table[0], 0x00,
896 sizeof(Slave->a.misc_flags_table));
897 memset(&Slave->a.rx_stream[0], 0x00,
898 sizeof(Slave->a.rx_stream));
899 memset(&Slave->a.tx_stream[0], 0x00,
900 sizeof(Slave->a.tx_stream));
901 memset(&Slave->a.tx_pos[0], 0x00, sizeof(Slave->a.tx_pos));
902 memset(&Slave->a.rx_pos[0], 0x00, sizeof(Slave->a.rx_pos));
903 }
904
905 return (0);
906}
907
908
909static int
910diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
911 dword address,
912 const byte *data, dword length, dword limit)
913{
914 byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
915 byte __iomem *mem = p;
916
917 if (((address + length) >= limit) || !mem) {
918 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
919 DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
920 IoAdapter->ANum, address + length))
921 return (-1);
922 }
923 mem += address;
924
925 while (length--) {
926 WRITE_BYTE(mem++, *data++);
927 }
928
929 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
930 return (0);
931}
932
933static int
934diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
935 dword start_address, dword features)
936{
937 volatile word __iomem *signature;
938 int started = 0;
939 int i;
940 byte __iomem *p;
941
942 /*
943 start adapter
944 */
945 start_qBri_hardware(IoAdapter);
946
947 p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
948 /*
949 wait for signature in shared memory (max. 3 seconds)
950 */
951 signature = (volatile word __iomem *) (&p[0x1E]);
952
953 for (i = 0; i < 300; ++i) {
954 diva_os_wait(10);
955 if (READ_WORD(&signature[0]) == 0x4447) {
956 DBG_TRC(("Protocol startup time %d.%02d seconds",
957 (i / 100), (i % 100)))
958 started = 1;
959 break;
960 }
961 }
962
963 for (i = 1; i < IoAdapter->tasks; i++) {
964 IoAdapter->QuadroList->QuadroAdapter[i]->features =
965 IoAdapter->features;
966 IoAdapter->QuadroList->QuadroAdapter[i]->a.
967 protocol_capabilities = IoAdapter->features;
968 }
969
970 if (!started) {
971 DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
972 IoAdapter->Properties.Name,
973 READ_WORD(&signature[0])))
974 DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
975 (*(IoAdapter->trapFnc)) (IoAdapter);
976 IoAdapter->stop(IoAdapter);
977 return (-1);
978 }
979 DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
980
981 for (i = 0; i < IoAdapter->tasks; i++) {
982 IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
983 IoAdapter->QuadroList->QuadroAdapter[i]->IrqCount = 0;
984 }
985
986 if (check_qBri_interrupt(IoAdapter)) {
987 DBG_ERR(("A: A(%d) interrupt test failed",
988 IoAdapter->ANum))
989 for (i = 0; i < IoAdapter->tasks; i++) {
990 IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
991 }
992 IoAdapter->stop(IoAdapter);
993 return (-1);
994 }
995
996 IoAdapter->Properties.Features = (word) features;
997 diva_xdi_display_adapter_features(IoAdapter->ANum);
998
999 for (i = 0; i < IoAdapter->tasks; i++) {
1000 DBG_LOG(("A(%d) %s adapter successfully started",
1001 IoAdapter->QuadroList->QuadroAdapter[i]->ANum,
1002 (IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI"))
1003 diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
1004 IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features;
1005 }
1006
1007 return (0);
1008}
1009
1010static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
1011{
1012#ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI
1013 int i;
1014 ADAPTER *a = &IoAdapter->a;
1015 byte __iomem *p;
1016
1017 IoAdapter->IrqCount = 0;
1018
1019 if (IoAdapter->ControllerNumber > 0)
1020 return (-1);
1021
1022 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
1023 WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
1024 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
1025 /*
1026 interrupt test
1027 */
1028 a->ReadyInt = 1;
1029 a->ram_out(a, &PR_RAM->ReadyInt, 1);
1030
1031 for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
1032
1033 return ((IoAdapter->IrqCount > 0) ? 0 : -1);
1034#else
1035 dword volatile __iomem *qBriIrq;
1036 byte __iomem *p;
1037 /*
1038 Reset on-board interrupt register
1039 */
1040 IoAdapter->IrqCount = 0;
1041 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
1042 qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card
1043 (IoAdapter->
1044 cardType) ? (MQ2_BREG_IRQ_TEST)
1045 : (MQ_BREG_IRQ_TEST)]);
1046
1047 WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
1048 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
1049
1050 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
1051 WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
1052 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
1053
1054 diva_os_wait(100);
1055
1056 return (0);
1057#endif /* SUPPORT_INTERRUPT_TEST_ON_4BRI */
1058}
1059
1060static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t *a)
1061{
1062 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
1063
1064 /*
1065 clear any pending interrupt
1066 */
1067 IoAdapter->disIrq(IoAdapter);
1068
1069 IoAdapter->tst_irq(&IoAdapter->a);
1070 IoAdapter->clr_irq(&IoAdapter->a);
1071 IoAdapter->tst_irq(&IoAdapter->a);
1072
1073 /*
1074 kill pending dpcs
1075 */
1076 diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
1077 diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
1078}
1079
1080static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a)
1081{
1082 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
1083 int i;
1084
1085 if (!IoAdapter->ram) {
1086 return (-1);
1087 }
1088
1089 if (!IoAdapter->Initialized) {
1090 DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
1091 IoAdapter->ANum))
1092 return (-1); /* nothing to stop */
1093 }
1094
1095 for (i = 0; i < IoAdapter->tasks; i++) {
1096 IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
1097 }
1098
1099 /*
1100 Disconnect Adapters from DIDD
1101 */
1102 for (i = 0; i < IoAdapter->tasks; i++) {
1103 diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
1104 }
1105
1106 i = 100;
1107
1108 /*
1109 Stop interrupts
1110 */
1111 a->clear_interrupts_proc = diva_4bri_clear_interrupts;
1112 IoAdapter->a.ReadyInt = 1;
1113 IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
1114 do {
1115 diva_os_sleep(10);
1116 } while (i-- && a->clear_interrupts_proc);
1117
1118 if (a->clear_interrupts_proc) {
1119 diva_4bri_clear_interrupts(a);
1120 a->clear_interrupts_proc = NULL;
1121 DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter",
1122 IoAdapter->ANum))
1123 }
1124 IoAdapter->a.ReadyInt = 0;
1125
1126 /*
1127 Stop and reset adapter
1128 */
1129 IoAdapter->stop(IoAdapter);
1130
1131 return (0);
1132}
diff --git a/drivers/isdn/hardware/eicon/os_4bri.h b/drivers/isdn/hardware/eicon/os_4bri.h
deleted file mode 100644
index 94b2709537d8..000000000000
--- a/drivers/isdn/hardware/eicon/os_4bri.h
+++ /dev/null
@@ -1,9 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: os_4bri.h,v 1.1.2.2 2001/02/08 12:25:44 armin Exp $ */
3
4#ifndef __DIVA_OS_4_BRI_H__
5#define __DIVA_OS_4_BRI_H__
6
7int diva_4bri_init_card(diva_os_xdi_adapter_t *a);
8
9#endif
diff --git a/drivers/isdn/hardware/eicon/os_bri.c b/drivers/isdn/hardware/eicon/os_bri.c
deleted file mode 100644
index de93090bcacb..000000000000
--- a/drivers/isdn/hardware/eicon/os_bri.c
+++ /dev/null
@@ -1,815 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/* $Id: os_bri.c,v 1.21 2004/03/21 17:26:01 armin Exp $ */
3
4#include "platform.h"
5#include "debuglib.h"
6#include "cardtype.h"
7#include "pc.h"
8#include "pr_pc.h"
9#include "di_defs.h"
10#include "dsp_defs.h"
11#include "di.h"
12#include "io.h"
13
14#include "xdi_msg.h"
15#include "xdi_adapter.h"
16#include "os_bri.h"
17#include "diva_pci.h"
18#include "mi_pc.h"
19#include "pc_maint.h"
20#include "dsrv_bri.h"
21
22/*
23** IMPORTS
24*/
25extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
26extern void diva_xdi_display_adapter_features(int card);
27extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
28
29/*
30** LOCALS
31*/
32static int bri_bar_length[3] = {
33 0x80,
34 0x80,
35 0x20
36};
37static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
38static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a);
39static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
40 diva_xdi_um_cfg_cmd_t *cmd, int length);
41static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a);
42static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter);
43static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
44 dword address,
45 const byte *data, dword length);
46static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
47 dword start_address, dword features);
48static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a);
49
50static void diva_bri_set_addresses(diva_os_xdi_adapter_t *a)
51{
52 a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
53 a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
54 a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
55 a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
56 a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
57 a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
58
59 a->xdi_adapter.ram = a->resources.pci.addr[0];
60 a->xdi_adapter.cfg = a->resources.pci.addr[1];
61 a->xdi_adapter.Address = a->resources.pci.addr[2];
62
63 a->xdi_adapter.reset = a->xdi_adapter.cfg;
64 a->xdi_adapter.port = a->xdi_adapter.Address;
65
66 a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
67
68 a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
69}
70
71/*
72** BAR0 - MEM Addr - 0x80 - NOT USED
73** BAR1 - I/O Addr - 0x80
74** BAR2 - I/O Addr - 0x20
75*/
76int diva_bri_init_card(diva_os_xdi_adapter_t *a)
77{
78 int bar;
79 dword bar2 = 0, bar2_length = 0xffffffff;
80 word cmd = 0, cmd_org;
81 byte Bus, Slot;
82 void *hdev;
83 byte __iomem *p;
84
85 /*
86 Set properties
87 */
88 a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
89 DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
90
91 /*
92 Get resources
93 */
94 for (bar = 0; bar < 3; bar++) {
95 a->resources.pci.bar[bar] =
96 divasa_get_pci_bar(a->resources.pci.bus,
97 a->resources.pci.func, bar,
98 a->resources.pci.hdev);
99 if (!a->resources.pci.bar[bar]) {
100 DBG_ERR(("A: can't get BAR[%d]", bar))
101 return (-1);
102 }
103 }
104
105 a->resources.pci.irq =
106 (byte) divasa_get_pci_irq(a->resources.pci.bus,
107 a->resources.pci.func,
108 a->resources.pci.hdev);
109 if (!a->resources.pci.irq) {
110 DBG_ERR(("A: invalid irq"));
111 return (-1);
112 }
113
114 /*
115 Get length of I/O bar 2 - it is different by older
116 EEPROM version
117 */
118 Bus = a->resources.pci.bus;
119 Slot = a->resources.pci.func;
120 hdev = a->resources.pci.hdev;
121
122 /*
123 Get plain original values of the BAR2 CDM registers
124 */
125 PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
126 PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
127 /*
128 Disable device and get BAR2 length
129 */
130 PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
131 PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
132 PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
133 /*
134 Restore BAR2 and CMD registers
135 */
136 PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
137 PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
138
139 /*
140 Calculate BAR2 length
141 */
142 bar2_length = (~(bar2_length & ~7)) + 1;
143 DBG_LOG(("BAR[2] length=%lx", bar2_length))
144
145 /*
146 Map and register resources
147 */
148 if (!(a->resources.pci.addr[0] =
149 divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
150 bri_bar_length[0]))) {
151 DBG_ERR(("A: BRI, can't map BAR[0]"))
152 diva_bri_cleanup_adapter(a);
153 return (-1);
154 }
155
156 sprintf(&a->port_name[0], "BRI %02x:%02x",
157 a->resources.pci.bus, a->resources.pci.func);
158
159 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
160 bri_bar_length[1], &a->port_name[0], 1)) {
161 DBG_ERR(("A: BRI, can't register BAR[1]"))
162 diva_bri_cleanup_adapter(a);
163 return (-1);
164 }
165 a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
166 a->resources.pci.length[1] = bri_bar_length[1];
167
168 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
169 bar2_length, &a->port_name[0], 2)) {
170 DBG_ERR(("A: BRI, can't register BAR[2]"))
171 diva_bri_cleanup_adapter(a);
172 return (-1);
173 }
174 a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2];
175 a->resources.pci.length[2] = bar2_length;
176
177 /*
178 Set all memory areas
179 */
180 diva_bri_set_addresses(a);
181
182 /*
183 Get Serial Number
184 */
185 a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
186
187 /*
188 Register I/O ports with correct name now
189 */
190 if (diva_bri_reregister_io(a)) {
191 diva_bri_cleanup_adapter(a);
192 return (-1);
193 }
194
195 /*
196 Initialize OS dependent objects
197 */
198 if (diva_os_initialize_spin_lock
199 (&a->xdi_adapter.isr_spin_lock, "isr")) {
200 diva_bri_cleanup_adapter(a);
201 return (-1);
202 }
203 if (diva_os_initialize_spin_lock
204 (&a->xdi_adapter.data_spin_lock, "data")) {
205 diva_bri_cleanup_adapter(a);
206 return (-1);
207 }
208
209 strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasbrid");
210
211 if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
212 DIDpcRoutine, &a->xdi_adapter)) {
213 diva_bri_cleanup_adapter(a);
214 return (-1);
215 }
216 /*
217 Do not initialize second DPC - only one thread will be created
218 */
219 a->xdi_adapter.isr_soft_isr.object = a->xdi_adapter.req_soft_isr.object;
220
221 /*
222 Create entity table
223 */
224 a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
225 a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
226 a->xdi_adapter.e_tbl = diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
227 if (!a->xdi_adapter.e_tbl) {
228 diva_bri_cleanup_adapter(a);
229 return (-1);
230 }
231 memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
232
233 /*
234 Set up interface
235 */
236 a->xdi_adapter.a.io = &a->xdi_adapter;
237 a->xdi_adapter.DIRequest = request;
238 a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
239 a->interface.cmd_proc = diva_bri_cmd_card_proc;
240
241 p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
242 outpp(p, 0x41);
243 DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
244
245 prepare_maestra_functions(&a->xdi_adapter);
246
247 a->dsp_mask = 0x00000003;
248
249 /*
250 Set IRQ handler
251 */
252 a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
253 sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %ld",
254 (long) a->xdi_adapter.serialNo);
255 if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
256 a->xdi_adapter.irq_info.irq_name)) {
257 diva_bri_cleanup_adapter(a);
258 return (-1);
259 }
260 a->xdi_adapter.irq_info.registered = 1;
261
262 diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
263 a->resources.pci.irq, a->xdi_adapter.serialNo);
264
265 return (0);
266}
267
268
269static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
270{
271 int i;
272
273 if (a->xdi_adapter.Initialized) {
274 diva_bri_stop_adapter(a);
275 }
276
277 /*
278 Remove ISR Handler
279 */
280 if (a->xdi_adapter.irq_info.registered) {
281 diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
282 }
283 a->xdi_adapter.irq_info.registered = 0;
284
285 if (a->resources.pci.addr[0] && a->resources.pci.bar[0]) {
286 divasa_unmap_pci_bar(a->resources.pci.addr[0]);
287 a->resources.pci.addr[0] = NULL;
288 a->resources.pci.bar[0] = 0;
289 }
290
291 for (i = 1; i < 3; i++) {
292 if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
293 diva_os_register_io_port(a, 0,
294 a->resources.pci.bar[i],
295 a->resources.pci.
296 length[i],
297 &a->port_name[0], i);
298 a->resources.pci.addr[i] = NULL;
299 a->resources.pci.bar[i] = 0;
300 }
301 }
302
303 /*
304 Free OS objects
305 */
306 diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
307 diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
308
309 diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
310 a->xdi_adapter.isr_soft_isr.object = NULL;
311
312 diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
313 diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
314
315 /*
316 Free memory
317 */
318 if (a->xdi_adapter.e_tbl) {
319 diva_os_free(0, a->xdi_adapter.e_tbl);
320 a->xdi_adapter.e_tbl = NULL;
321 }
322
323 return (0);
324}
325
326void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter)
327{
328}
329
330/*
331** Get serial number
332*/
333static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a)
334{
335 dword serNo = 0;
336 byte __iomem *confIO;
337 word serHi, serLo;
338 word __iomem *confMem;
339
340 confIO = DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
341 serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
342 serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
343 serNo = ((dword) serHi << 16) | (dword) serLo;
344 DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);
345
346 if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
347 DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
348
349 confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
350 serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
351 serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
352 serNo = (((dword) serHi) << 16) | ((dword) serLo);
353 DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
354 }
355
356 DBG_LOG(("Serial Number=%ld", serNo))
357
358 return (serNo);
359}
360
361/*
362** Unregister I/O and register it with new name,
363** based on Serial Number
364*/
365static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a)
366{
367 int i;
368
369 for (i = 1; i < 3; i++) {
370 diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
371 a->resources.pci.length[i],
372 &a->port_name[0], i);
373 a->resources.pci.addr[i] = NULL;
374 }
375
376 sprintf(a->port_name, "DIVA BRI %ld",
377 (long) a->xdi_adapter.serialNo);
378
379 for (i = 1; i < 3; i++) {
380 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
381 a->resources.pci.length[i],
382 &a->port_name[0], i)) {
383 DBG_ERR(("A: failed to reregister BAR[%d]", i))
384 return (-1);
385 }
386 a->resources.pci.addr[i] =
387 (void *) (unsigned long) a->resources.pci.bar[i];
388 }
389
390 return (0);
391}
392
393/*
394** Process command from user mode
395*/
396static int
397diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
398 diva_xdi_um_cfg_cmd_t *cmd, int length)
399{
400 int ret = -1;
401
402 if (cmd->adapter != a->controller) {
403 DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
404 cmd->adapter, a->controller))
405 return (-1);
406 }
407
408 switch (cmd->command) {
409 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
410 a->xdi_mbox.data_length = sizeof(dword);
411 a->xdi_mbox.data =
412 diva_os_malloc(0, a->xdi_mbox.data_length);
413 if (a->xdi_mbox.data) {
414 *(dword *) a->xdi_mbox.data =
415 (dword) a->CardOrdinal;
416 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
417 ret = 0;
418 }
419 break;
420
421 case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
422 a->xdi_mbox.data_length = sizeof(dword);
423 a->xdi_mbox.data =
424 diva_os_malloc(0, a->xdi_mbox.data_length);
425 if (a->xdi_mbox.data) {
426 *(dword *) a->xdi_mbox.data =
427 (dword) a->xdi_adapter.serialNo;
428 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
429 ret = 0;
430 }
431 break;
432
433 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
434 a->xdi_mbox.data_length = sizeof(dword) * 9;
435 a->xdi_mbox.data =
436 diva_os_malloc(0, a->xdi_mbox.data_length);
437 if (a->xdi_mbox.data) {
438 int i;
439 dword *data = (dword *) a->xdi_mbox.data;
440
441 for (i = 0; i < 8; i++) {
442 *data++ = a->resources.pci.bar[i];
443 }
444 *data++ = (dword) a->resources.pci.irq;
445 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
446 ret = 0;
447 }
448 break;
449
450 case DIVA_XDI_UM_CMD_GET_CARD_STATE:
451 a->xdi_mbox.data_length = sizeof(dword);
452 a->xdi_mbox.data =
453 diva_os_malloc(0, a->xdi_mbox.data_length);
454 if (a->xdi_mbox.data) {
455 dword *data = (dword *) a->xdi_mbox.data;
456 if (!a->xdi_adapter.port) {
457 *data = 3;
458 } else if (a->xdi_adapter.trapped) {
459 *data = 2;
460 } else if (a->xdi_adapter.Initialized) {
461 *data = 1;
462 } else {
463 *data = 0;
464 }
465 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
466 ret = 0;
467 }
468 break;
469
470 case DIVA_XDI_UM_CMD_RESET_ADAPTER:
471 ret = diva_bri_reset_adapter(&a->xdi_adapter);
472 break;
473
474 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
475 ret = diva_bri_write_sdram_block(&a->xdi_adapter,
476 cmd->command_data.
477 write_sdram.offset,
478 (byte *)&cmd[1],
479 cmd->command_data.
480 write_sdram.length);
481 break;
482
483 case DIVA_XDI_UM_CMD_START_ADAPTER:
484 ret = diva_bri_start_adapter(&a->xdi_adapter,
485 cmd->command_data.start.
486 offset,
487 cmd->command_data.start.
488 features);
489 break;
490
491 case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
492 a->xdi_adapter.features =
493 cmd->command_data.features.features;
494 a->xdi_adapter.a.protocol_capabilities =
495 a->xdi_adapter.features;
496 DBG_TRC(
497 ("Set raw protocol features (%08x)",
498 a->xdi_adapter.features)) ret = 0;
499 break;
500
501 case DIVA_XDI_UM_CMD_STOP_ADAPTER:
502 ret = diva_bri_stop_adapter(a);
503 break;
504
505 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
506 ret = diva_card_read_xlog(a);
507 break;
508
509 default:
510 DBG_ERR(
511 ("A: A(%d) invalid cmd=%d", a->controller,
512 cmd->command))}
513
514 return (ret);
515}
516
517static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
518{
519 byte __iomem *addrHi, *addrLo, *ioaddr;
520 dword i;
521 byte __iomem *Port;
522
523 if (!IoAdapter->port) {
524 return (-1);
525 }
526 if (IoAdapter->Initialized) {
527 DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
528 IoAdapter->ANum)) return (-1);
529 }
530 (*(IoAdapter->rstFnc)) (IoAdapter);
531 diva_os_wait(100);
532 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
533 addrHi = Port +
534 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
535 addrLo = Port + ADDR;
536 ioaddr = Port + DATA;
537 /*
538 recover
539 */
540 outpp(addrHi, (byte) 0);
541 outppw(addrLo, (word) 0);
542 outppw(ioaddr, (word) 0);
543 /*
544 clear shared memory
545 */
546 outpp(addrHi,
547 (byte) (
548 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
549 BRI_SHARED_RAM_SIZE) >> 16));
550 outppw(addrLo, 0);
551 for (i = 0; i < 0x8000; outppw(ioaddr, 0), ++i);
552 diva_os_wait(100);
553
554 /*
555 clear signature
556 */
557 outpp(addrHi,
558 (byte) (
559 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
560 BRI_SHARED_RAM_SIZE) >> 16));
561 outppw(addrLo, 0x1e);
562 outpp(ioaddr, 0);
563 outpp(ioaddr, 0);
564
565 outpp(addrHi, (byte) 0);
566 outppw(addrLo, (word) 0);
567 outppw(ioaddr, (word) 0);
568
569 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
570
571 /*
572 Forget all outstanding entities
573 */
574 IoAdapter->e_count = 0;
575 if (IoAdapter->e_tbl) {
576 memset(IoAdapter->e_tbl, 0x00,
577 IoAdapter->e_max * sizeof(E_INFO));
578 }
579 IoAdapter->head = 0;
580 IoAdapter->tail = 0;
581 IoAdapter->assign = 0;
582 IoAdapter->trapped = 0;
583
584 memset(&IoAdapter->a.IdTable[0], 0x00,
585 sizeof(IoAdapter->a.IdTable));
586 memset(&IoAdapter->a.IdTypeTable[0], 0x00,
587 sizeof(IoAdapter->a.IdTypeTable));
588 memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
589 sizeof(IoAdapter->a.FlowControlIdTable));
590 memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
591 sizeof(IoAdapter->a.FlowControlSkipTable));
592 memset(&IoAdapter->a.misc_flags_table[0], 0x00,
593 sizeof(IoAdapter->a.misc_flags_table));
594 memset(&IoAdapter->a.rx_stream[0], 0x00,
595 sizeof(IoAdapter->a.rx_stream));
596 memset(&IoAdapter->a.tx_stream[0], 0x00,
597 sizeof(IoAdapter->a.tx_stream));
598 memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
599 memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
600
601 return (0);
602}
603
604static int
605diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
606 dword address, const byte *data, dword length)
607{
608 byte __iomem *addrHi, *addrLo, *ioaddr;
609 byte __iomem *Port;
610
611 if (!IoAdapter->port) {
612 return (-1);
613 }
614
615 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
616 addrHi = Port +
617 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
618 addrLo = Port + ADDR;
619 ioaddr = Port + DATA;
620
621 while (length--) {
622 outpp(addrHi, (word) (address >> 16));
623 outppw(addrLo, (word) (address & 0x0000ffff));
624 outpp(ioaddr, *data++);
625 address++;
626 }
627
628 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
629 return (0);
630}
631
632static int
633diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
634 dword start_address, dword features)
635{
636 byte __iomem *Port;
637 dword i, test;
638 byte __iomem *addrHi, *addrLo, *ioaddr;
639 int started = 0;
640 ADAPTER *a = &IoAdapter->a;
641
642 if (IoAdapter->Initialized) {
643 DBG_ERR(
644 ("A: A(%d) bri_start_adapter, adapter already running",
645 IoAdapter->ANum)) return (-1);
646 }
647 if (!IoAdapter->port) {
648 DBG_ERR(("A: A(%d) bri_start_adapter, adapter not mapped",
649 IoAdapter->ANum)) return (-1);
650 }
651
652 sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
653 DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
654
655 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
656 addrHi = Port +
657 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
658 addrLo = Port + ADDR;
659 ioaddr = Port + DATA;
660
661 outpp(addrHi,
662 (byte) (
663 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
664 BRI_SHARED_RAM_SIZE) >> 16));
665 outppw(addrLo, 0x1e);
666 outppw(ioaddr, 0x00);
667 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
668
669 /*
670 start the protocol code
671 */
672 Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
673 outpp(Port, 0x08);
674 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
675
676 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
677 addrHi = Port +
678 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
679 addrLo = Port + ADDR;
680 ioaddr = Port + DATA;
681 /*
682 wait for signature (max. 3 seconds)
683 */
684 for (i = 0; i < 300; ++i) {
685 diva_os_wait(10);
686 outpp(addrHi,
687 (byte) (
688 (IoAdapter->MemoryBase +
689 IoAdapter->MemorySize -
690 BRI_SHARED_RAM_SIZE) >> 16));
691 outppw(addrLo, 0x1e);
692 test = (dword) inppw(ioaddr);
693 if (test == 0x4447) {
694 DBG_LOG(
695 ("Protocol startup time %d.%02d seconds",
696 (i / 100), (i % 100)))
697 started = 1;
698 break;
699 }
700 }
701 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
702
703 if (!started) {
704 DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
705 IoAdapter->ANum, IoAdapter->Properties.Name,
706 test))
707 (*(IoAdapter->trapFnc)) (IoAdapter);
708 return (-1);
709 }
710
711 IoAdapter->Initialized = 1;
712
713 /*
714 Check Interrupt
715 */
716 IoAdapter->IrqCount = 0;
717 a->ReadyInt = 1;
718
719 if (IoAdapter->reset) {
720 Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
721 outpp(Port, 0x41);
722 DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
723 }
724
725 a->ram_out(a, &PR_RAM->ReadyInt, 1);
726 for (i = 0; ((!IoAdapter->IrqCount) && (i < 100)); i++) {
727 diva_os_wait(10);
728 }
729 if (!IoAdapter->IrqCount) {
730 DBG_ERR(
731 ("A: A(%d) interrupt test failed",
732 IoAdapter->ANum))
733 IoAdapter->Initialized = 0;
734 IoAdapter->stop(IoAdapter);
735 return (-1);
736 }
737
738 IoAdapter->Properties.Features = (word) features;
739 diva_xdi_display_adapter_features(IoAdapter->ANum);
740 DBG_LOG(("A(%d) BRI adapter successfully started", IoAdapter->ANum))
741 /*
742 Register with DIDD
743 */
744 diva_xdi_didd_register_adapter(IoAdapter->ANum);
745
746 return (0);
747}
748
749static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t *a)
750{
751 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
752
753 /*
754 clear any pending interrupt
755 */
756 IoAdapter->disIrq(IoAdapter);
757
758 IoAdapter->tst_irq(&IoAdapter->a);
759 IoAdapter->clr_irq(&IoAdapter->a);
760 IoAdapter->tst_irq(&IoAdapter->a);
761
762 /*
763 kill pending dpcs
764 */
765 diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
766 diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
767}
768
769/*
770** Stop card
771*/
772static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a)
773{
774 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
775 int i = 100;
776
777 if (!IoAdapter->port) {
778 return (-1);
779 }
780 if (!IoAdapter->Initialized) {
781 DBG_ERR(("A: A(%d) can't stop BRI adapter - not running",
782 IoAdapter->ANum))
783 return (-1); /* nothing to stop */
784 }
785 IoAdapter->Initialized = 0;
786
787 /*
788 Disconnect Adapter from DIDD
789 */
790 diva_xdi_didd_remove_adapter(IoAdapter->ANum);
791
792 /*
793 Stop interrupts
794 */
795 a->clear_interrupts_proc = diva_bri_clear_interrupts;
796 IoAdapter->a.ReadyInt = 1;
797 IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
798 do {
799 diva_os_sleep(10);
800 } while (i-- && a->clear_interrupts_proc);
801 if (a->clear_interrupts_proc) {
802 diva_bri_clear_interrupts(a);
803 a->clear_interrupts_proc = NULL;
804 DBG_ERR(("A: A(%d) no final interrupt from BRI adapter",
805 IoAdapter->ANum))
806 }
807 IoAdapter->a.ReadyInt = 0;
808
809 /*
810 Stop and reset adapter
811 */
812 IoAdapter->stop(IoAdapter);
813
814 return (0);
815}
diff --git a/drivers/isdn/hardware/eicon/os_bri.h b/drivers/isdn/hardware/eicon/os_bri.h
deleted file mode 100644
index 37c92cc53ded..000000000000
--- a/drivers/isdn/hardware/eicon/os_bri.h
+++ /dev/null
@@ -1,9 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: os_bri.h,v 1.1.2.2 2001/02/08 12:25:44 armin Exp $ */
3
4#ifndef __DIVA_OS_BRI_REV_1_H__
5#define __DIVA_OS_BRI_REV_1_H__
6
7int diva_bri_init_card(diva_os_xdi_adapter_t *a);
8
9#endif
diff --git a/drivers/isdn/hardware/eicon/os_capi.h b/drivers/isdn/hardware/eicon/os_capi.h
deleted file mode 100644
index e72394b95d50..000000000000
--- a/drivers/isdn/hardware/eicon/os_capi.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/* $Id: os_capi.h,v 1.7 2003/04/12 21:40:49 schindler Exp $
2 *
3 * ISDN interface module for Eicon active cards DIVA.
4 * CAPI Interface OS include files
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#ifndef __OS_CAPI_H__
14#define __OS_CAPI_H__
15
16#include <linux/capi.h>
17#include <linux/kernelcapi.h>
18#include <linux/isdn/capiutil.h>
19#include <linux/isdn/capilli.h>
20
21#endif /* __OS_CAPI_H__ */
diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c
deleted file mode 100644
index b20f1fb89d14..000000000000
--- a/drivers/isdn/hardware/eicon/os_pri.c
+++ /dev/null
@@ -1,1053 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/* $Id: os_pri.c,v 1.32 2004/03/21 17:26:01 armin Exp $ */
3
4#include "platform.h"
5#include "debuglib.h"
6#include "cardtype.h"
7#include "pc.h"
8#include "pr_pc.h"
9#include "di_defs.h"
10#include "dsp_defs.h"
11#include "di.h"
12#include "io.h"
13
14#include "xdi_msg.h"
15#include "xdi_adapter.h"
16#include "os_pri.h"
17#include "diva_pci.h"
18#include "mi_pc.h"
19#include "pc_maint.h"
20#include "dsp_tst.h"
21#include "diva_dma.h"
22#include "dsrv_pri.h"
23
24/* --------------------------------------------------------------------------
25 OS Dependent part of XDI driver for DIVA PRI Adapter
26
27 DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
28 -------------------------------------------------------------------------- */
29
30#define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1
31
32extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
33
34/*
35** IMPORTS
36*/
37extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
38extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
39extern void diva_xdi_display_adapter_features(int card);
40
41static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a);
42static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
43 diva_xdi_um_cfg_cmd_t *cmd, int length);
44static int pri_get_serial_number(diva_os_xdi_adapter_t *a);
45static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a);
46static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a);
47
48/*
49** Check card revision
50*/
51static int pri_is_rev_2_card(int card_ordinal)
52{
53 switch (card_ordinal) {
54 case CARDTYPE_DIVASRV_P_30M_V2_PCI:
55 case CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI:
56 return (1);
57 }
58 return (0);
59}
60
61static void diva_pri_set_addresses(diva_os_xdi_adapter_t *a)
62{
63 a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
64 a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
65 a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
66 a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
67 a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
68 a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
69 a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
70
71 a->xdi_adapter.Address = a->resources.pci.addr[0];
72 a->xdi_adapter.Control = a->resources.pci.addr[2];
73 a->xdi_adapter.Config = a->resources.pci.addr[4];
74
75 a->xdi_adapter.ram = a->resources.pci.addr[0];
76 a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
77
78 a->xdi_adapter.reset = a->resources.pci.addr[2];
79 a->xdi_adapter.reset += MP_RESET;
80
81 a->xdi_adapter.cfg = a->resources.pci.addr[4];
82 a->xdi_adapter.cfg += MP_IRQ_RESET;
83
84 a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
85
86 a->xdi_adapter.prom = a->resources.pci.addr[3];
87}
88
89/*
90** BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
91** BAR1 - DEVICES, 0x1000
92** BAR2 - CONTROL (REG), 0x2000
93** BAR3 - FLASH (REG), 0x8000
94** BAR4 - CONFIG (CFG), 0x1000
95*/
96int diva_pri_init_card(diva_os_xdi_adapter_t *a)
97{
98 int bar = 0;
99 int pri_rev_2;
100 unsigned long bar_length[5] = {
101 MP_MEMORY_SIZE,
102 0x1000,
103 0x2000,
104 0x8000,
105 0x1000
106 };
107
108 pri_rev_2 = pri_is_rev_2_card(a->CardOrdinal);
109
110 if (pri_rev_2) {
111 bar_length[0] = MP2_MEMORY_SIZE;
112 }
113 /*
114 Set properties
115 */
116 a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
117 DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
118
119 /*
120 First initialization step: get and check hardware resoures.
121 Do not map resources and do not acecess card at this step
122 */
123 for (bar = 0; bar < 5; bar++) {
124 a->resources.pci.bar[bar] =
125 divasa_get_pci_bar(a->resources.pci.bus,
126 a->resources.pci.func, bar,
127 a->resources.pci.hdev);
128 if (!a->resources.pci.bar[bar]
129 || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
130 DBG_ERR(("A: invalid bar[%d]=%08x", bar,
131 a->resources.pci.bar[bar]))
132 return (-1);
133 }
134 }
135 a->resources.pci.irq =
136 (byte) divasa_get_pci_irq(a->resources.pci.bus,
137 a->resources.pci.func,
138 a->resources.pci.hdev);
139 if (!a->resources.pci.irq) {
140 DBG_ERR(("A: invalid irq"));
141 return (-1);
142 }
143
144 /*
145 Map all BAR's
146 */
147 for (bar = 0; bar < 5; bar++) {
148 a->resources.pci.addr[bar] =
149 divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
150 bar_length[bar]);
151 if (!a->resources.pci.addr[bar]) {
152 DBG_ERR(("A: A(%d), can't map bar[%d]",
153 a->controller, bar))
154 diva_pri_cleanup_adapter(a);
155 return (-1);
156 }
157 }
158
159 /*
160 Set all memory areas
161 */
162 diva_pri_set_addresses(a);
163
164 /*
165 Get Serial Number of this adapter
166 */
167 if (pri_get_serial_number(a)) {
168 dword serNo;
169 serNo = a->resources.pci.bar[1] & 0xffff0000;
170 serNo |= ((dword) a->resources.pci.bus) << 8;
171 serNo += (a->resources.pci.func + a->controller + 1);
172 a->xdi_adapter.serialNo = serNo & ~0xFF000000;
173 DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
174 a->controller, a->xdi_adapter.serialNo))
175 }
176
177
178 /*
179 Initialize os objects
180 */
181 if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
182 diva_pri_cleanup_adapter(a);
183 return (-1);
184 }
185 if (diva_os_initialize_spin_lock
186 (&a->xdi_adapter.data_spin_lock, "data")) {
187 diva_pri_cleanup_adapter(a);
188 return (-1);
189 }
190
191 strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasprid");
192
193 if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
194 DIDpcRoutine, &a->xdi_adapter)) {
195 diva_pri_cleanup_adapter(a);
196 return (-1);
197 }
198
199 /*
200 Do not initialize second DPC - only one thread will be created
201 */
202 a->xdi_adapter.isr_soft_isr.object =
203 a->xdi_adapter.req_soft_isr.object;
204
205 /*
206 Next step of card initialization:
207 set up all interface pointers
208 */
209 a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
210 a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
211
212 a->xdi_adapter.e_tbl =
213 diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
214 if (!a->xdi_adapter.e_tbl) {
215 diva_pri_cleanup_adapter(a);
216 return (-1);
217 }
218 memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
219
220 a->xdi_adapter.a.io = &a->xdi_adapter;
221 a->xdi_adapter.DIRequest = request;
222 a->interface.cleanup_adapter_proc = diva_pri_cleanup_adapter;
223 a->interface.cmd_proc = diva_pri_cmd_card_proc;
224
225 if (pri_rev_2) {
226 prepare_pri2_functions(&a->xdi_adapter);
227 } else {
228 prepare_pri_functions(&a->xdi_adapter);
229 }
230
231 a->dsp_mask = diva_pri_detect_dsps(a);
232
233 /*
234 Allocate DMA map
235 */
236 if (pri_rev_2) {
237 diva_init_dma_map(a->resources.pci.hdev,
238 (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
239 }
240
241 /*
242 Set IRQ handler
243 */
244 a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
245 sprintf(a->xdi_adapter.irq_info.irq_name,
246 "DIVA PRI %ld", (long) a->xdi_adapter.serialNo);
247
248 if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
249 a->xdi_adapter.irq_info.irq_name)) {
250 diva_pri_cleanup_adapter(a);
251 return (-1);
252 }
253 a->xdi_adapter.irq_info.registered = 1;
254
255 diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
256 a->resources.pci.irq, a->xdi_adapter.serialNo);
257
258 return (0);
259}
260
261static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a)
262{
263 int bar = 0;
264
265 /*
266 Stop Adapter if adapter is running
267 */
268 if (a->xdi_adapter.Initialized) {
269 diva_pri_stop_adapter(a);
270 }
271
272 /*
273 Remove ISR Handler
274 */
275 if (a->xdi_adapter.irq_info.registered) {
276 diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
277 }
278 a->xdi_adapter.irq_info.registered = 0;
279
280 /*
281 Step 1: unmap all BAR's, if any was mapped
282 */
283 for (bar = 0; bar < 5; bar++) {
284 if (a->resources.pci.bar[bar]
285 && a->resources.pci.addr[bar]) {
286 divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
287 a->resources.pci.bar[bar] = 0;
288 a->resources.pci.addr[bar] = NULL;
289 }
290 }
291
292 /*
293 Free OS objects
294 */
295 diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
296 diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
297
298 diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
299 a->xdi_adapter.isr_soft_isr.object = NULL;
300
301 diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
302 diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
303
304 /*
305 Free memory accupied by XDI adapter
306 */
307 if (a->xdi_adapter.e_tbl) {
308 diva_os_free(0, a->xdi_adapter.e_tbl);
309 a->xdi_adapter.e_tbl = NULL;
310 }
311 a->xdi_adapter.Channels = 0;
312 a->xdi_adapter.e_max = 0;
313
314
315 /*
316 Free adapter DMA map
317 */
318 diva_free_dma_map(a->resources.pci.hdev,
319 (struct _diva_dma_map_entry *) a->xdi_adapter.
320 dma_map);
321 a->xdi_adapter.dma_map = NULL;
322
323
324 /*
325 Detach this adapter from debug driver
326 */
327
328 return (0);
329}
330
331/*
332** Activate On Board Boot Loader
333*/
334static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
335{
336 dword i;
337 struct mp_load __iomem *boot;
338
339 if (!IoAdapter->Address || !IoAdapter->reset) {
340 return (-1);
341 }
342 if (IoAdapter->Initialized) {
343 DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first",
344 IoAdapter->ANum))
345 return (-1);
346 }
347
348 boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
349 WRITE_DWORD(&boot->err, 0);
350 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
351
352 IoAdapter->rstFnc(IoAdapter);
353
354 diva_os_wait(10);
355
356 boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
357 i = READ_DWORD(&boot->live);
358
359 diva_os_wait(10);
360 if (i == READ_DWORD(&boot->live)) {
361 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
362 DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
363 IoAdapter->ANum, IoAdapter->serialNo))
364 return (-1);
365 }
366 if (READ_DWORD(&boot->err)) {
367 DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
368 IoAdapter->ANum, IoAdapter->serialNo,
369 READ_DWORD(&boot->err)))
370 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
371 return (-1);
372 }
373 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
374
375 /*
376 Forget all outstanding entities
377 */
378 IoAdapter->e_count = 0;
379 if (IoAdapter->e_tbl) {
380 memset(IoAdapter->e_tbl, 0x00,
381 IoAdapter->e_max * sizeof(E_INFO));
382 }
383 IoAdapter->head = 0;
384 IoAdapter->tail = 0;
385 IoAdapter->assign = 0;
386 IoAdapter->trapped = 0;
387
388 memset(&IoAdapter->a.IdTable[0], 0x00,
389 sizeof(IoAdapter->a.IdTable));
390 memset(&IoAdapter->a.IdTypeTable[0], 0x00,
391 sizeof(IoAdapter->a.IdTypeTable));
392 memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
393 sizeof(IoAdapter->a.FlowControlIdTable));
394 memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
395 sizeof(IoAdapter->a.FlowControlSkipTable));
396 memset(&IoAdapter->a.misc_flags_table[0], 0x00,
397 sizeof(IoAdapter->a.misc_flags_table));
398 memset(&IoAdapter->a.rx_stream[0], 0x00,
399 sizeof(IoAdapter->a.rx_stream));
400 memset(&IoAdapter->a.tx_stream[0], 0x00,
401 sizeof(IoAdapter->a.tx_stream));
402 memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
403 memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
404
405 return (0);
406}
407
408static int
409diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
410 dword address,
411 const byte *data, dword length, dword limit)
412{
413 byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
414 byte __iomem *mem = p;
415
416 if (((address + length) >= limit) || !mem) {
417 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
418 DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
419 IoAdapter->ANum, address + length))
420 return (-1);
421 }
422 mem += address;
423
424 /* memcpy_toio(), maybe? */
425 while (length--) {
426 WRITE_BYTE(mem++, *data++);
427 }
428
429 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
430 return (0);
431}
432
433static int
434diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
435 dword start_address, dword features)
436{
437 dword i;
438 int started = 0;
439 byte __iomem *p;
440 struct mp_load __iomem *boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
441 ADAPTER *a = &IoAdapter->a;
442
443 if (IoAdapter->Initialized) {
444 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
445 DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
446 IoAdapter->ANum))
447 return (-1);
448 }
449 if (!boot) {
450 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
451 DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
452 IoAdapter->serialNo))
453 return (-1);
454 }
455
456 sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
457 DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
458 start_address))
459
460 WRITE_DWORD(&boot->addr, start_address);
461 WRITE_DWORD(&boot->cmd, 3);
462
463 for (i = 0; i < 300; ++i) {
464 diva_os_wait(10);
465 if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
466 DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
467 IoAdapter->ANum, (i / 100), (i % 100)))
468 started = 1;
469 break;
470 }
471 }
472
473 if (!started) {
474 byte __iomem *p = (byte __iomem *)boot;
475 dword TrapId;
476 dword debug;
477 TrapId = READ_DWORD(&p[0x80]);
478 debug = READ_DWORD(&p[0x1c]);
479 DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
480 IoAdapter->ANum, READ_DWORD(&boot->signature),
481 TrapId, debug))
482 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
483 if (IoAdapter->trapFnc) {
484 (*(IoAdapter->trapFnc)) (IoAdapter);
485 }
486 IoAdapter->stop(IoAdapter);
487 return (-1);
488 }
489 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
490
491 IoAdapter->Initialized = true;
492
493 /*
494 Check Interrupt
495 */
496 IoAdapter->IrqCount = 0;
497 p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
498 WRITE_DWORD(p, (dword)~0x03E00000);
499 DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
500 a->ReadyInt = 1;
501 a->ram_out(a, &PR_RAM->ReadyInt, 1);
502
503 for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
504
505 if (!IoAdapter->IrqCount) {
506 DBG_ERR(("A: A(%d) interrupt test failed",
507 IoAdapter->ANum))
508 IoAdapter->Initialized = false;
509 IoAdapter->stop(IoAdapter);
510 return (-1);
511 }
512
513 IoAdapter->Properties.Features = (word) features;
514
515 diva_xdi_display_adapter_features(IoAdapter->ANum);
516
517 DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum))
518 /*
519 Register with DIDD
520 */
521 diva_xdi_didd_register_adapter(IoAdapter->ANum);
522
523 return (0);
524}
525
526static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t *a)
527{
528 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
529
530 /*
531 clear any pending interrupt
532 */
533 IoAdapter->disIrq(IoAdapter);
534
535 IoAdapter->tst_irq(&IoAdapter->a);
536 IoAdapter->clr_irq(&IoAdapter->a);
537 IoAdapter->tst_irq(&IoAdapter->a);
538
539 /*
540 kill pending dpcs
541 */
542 diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
543 diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
544}
545
546/*
547** Stop Adapter, but do not unmap/unregister - adapter
548** will be restarted later
549*/
550static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a)
551{
552 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
553 int i = 100;
554
555 if (!IoAdapter->ram) {
556 return (-1);
557 }
558 if (!IoAdapter->Initialized) {
559 DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
560 IoAdapter->ANum))
561 return (-1); /* nothing to stop */
562 }
563 IoAdapter->Initialized = 0;
564
565 /*
566 Disconnect Adapter from DIDD
567 */
568 diva_xdi_didd_remove_adapter(IoAdapter->ANum);
569
570 /*
571 Stop interrupts
572 */
573 a->clear_interrupts_proc = diva_pri_clear_interrupts;
574 IoAdapter->a.ReadyInt = 1;
575 IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
576 do {
577 diva_os_sleep(10);
578 } while (i-- && a->clear_interrupts_proc);
579
580 if (a->clear_interrupts_proc) {
581 diva_pri_clear_interrupts(a);
582 a->clear_interrupts_proc = NULL;
583 DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
584 IoAdapter->ANum))
585 }
586 IoAdapter->a.ReadyInt = 0;
587
588 /*
589 Stop and reset adapter
590 */
591 IoAdapter->stop(IoAdapter);
592
593 return (0);
594}
595
596/*
597** Process commands form configuration/download framework and from
598** user mode
599**
600** return 0 on success
601*/
602static int
603diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
604 diva_xdi_um_cfg_cmd_t *cmd, int length)
605{
606 int ret = -1;
607
608 if (cmd->adapter != a->controller) {
609 DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
610 cmd->adapter, a->controller))
611 return (-1);
612 }
613
614 switch (cmd->command) {
615 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
616 a->xdi_mbox.data_length = sizeof(dword);
617 a->xdi_mbox.data =
618 diva_os_malloc(0, a->xdi_mbox.data_length);
619 if (a->xdi_mbox.data) {
620 *(dword *) a->xdi_mbox.data =
621 (dword) a->CardOrdinal;
622 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
623 ret = 0;
624 }
625 break;
626
627 case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
628 a->xdi_mbox.data_length = sizeof(dword);
629 a->xdi_mbox.data =
630 diva_os_malloc(0, a->xdi_mbox.data_length);
631 if (a->xdi_mbox.data) {
632 *(dword *) a->xdi_mbox.data =
633 (dword) a->xdi_adapter.serialNo;
634 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
635 ret = 0;
636 }
637 break;
638
639 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
640 a->xdi_mbox.data_length = sizeof(dword) * 9;
641 a->xdi_mbox.data =
642 diva_os_malloc(0, a->xdi_mbox.data_length);
643 if (a->xdi_mbox.data) {
644 int i;
645 dword *data = (dword *) a->xdi_mbox.data;
646
647 for (i = 0; i < 8; i++) {
648 *data++ = a->resources.pci.bar[i];
649 }
650 *data++ = (dword) a->resources.pci.irq;
651 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
652 ret = 0;
653 }
654 break;
655
656 case DIVA_XDI_UM_CMD_RESET_ADAPTER:
657 ret = diva_pri_reset_adapter(&a->xdi_adapter);
658 break;
659
660 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
661 ret = diva_pri_write_sdram_block(&a->xdi_adapter,
662 cmd->command_data.
663 write_sdram.offset,
664 (byte *)&cmd[1],
665 cmd->command_data.
666 write_sdram.length,
667 pri_is_rev_2_card(a->
668 CardOrdinal)
669 ? MP2_MEMORY_SIZE :
670 MP_MEMORY_SIZE);
671 break;
672
673 case DIVA_XDI_UM_CMD_STOP_ADAPTER:
674 ret = diva_pri_stop_adapter(a);
675 break;
676
677 case DIVA_XDI_UM_CMD_START_ADAPTER:
678 ret = diva_pri_start_adapter(&a->xdi_adapter,
679 cmd->command_data.start.
680 offset,
681 cmd->command_data.start.
682 features);
683 break;
684
685 case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
686 a->xdi_adapter.features =
687 cmd->command_data.features.features;
688 a->xdi_adapter.a.protocol_capabilities =
689 a->xdi_adapter.features;
690 DBG_TRC(("Set raw protocol features (%08x)",
691 a->xdi_adapter.features))
692 ret = 0;
693 break;
694
695 case DIVA_XDI_UM_CMD_GET_CARD_STATE:
696 a->xdi_mbox.data_length = sizeof(dword);
697 a->xdi_mbox.data =
698 diva_os_malloc(0, a->xdi_mbox.data_length);
699 if (a->xdi_mbox.data) {
700 dword *data = (dword *) a->xdi_mbox.data;
701 if (!a->xdi_adapter.ram ||
702 !a->xdi_adapter.reset ||
703 !a->xdi_adapter.cfg) {
704 *data = 3;
705 } else if (a->xdi_adapter.trapped) {
706 *data = 2;
707 } else if (a->xdi_adapter.Initialized) {
708 *data = 1;
709 } else {
710 *data = 0;
711 }
712 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
713 ret = 0;
714 }
715 break;
716
717 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
718 ret = diva_card_read_xlog(a);
719 break;
720
721 case DIVA_XDI_UM_CMD_READ_SDRAM:
722 if (a->xdi_adapter.Address) {
723 if (
724 (a->xdi_mbox.data_length =
725 cmd->command_data.read_sdram.length)) {
726 if (
727 (a->xdi_mbox.data_length +
728 cmd->command_data.read_sdram.offset) <
729 a->xdi_adapter.MemorySize) {
730 a->xdi_mbox.data =
731 diva_os_malloc(0,
732 a->xdi_mbox.
733 data_length);
734 if (a->xdi_mbox.data) {
735 byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
736 byte __iomem *src = p;
737 byte *dst = a->xdi_mbox.data;
738 dword len = a->xdi_mbox.data_length;
739
740 src += cmd->command_data.read_sdram.offset;
741
742 while (len--) {
743 *dst++ = READ_BYTE(src++);
744 }
745 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
746 DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
747 ret = 0;
748 }
749 }
750 }
751 }
752 break;
753
754 default:
755 DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
756 cmd->command))
757 }
758
759 return (ret);
760}
761
762/*
763** Get Serial Number
764*/
765static int pri_get_serial_number(diva_os_xdi_adapter_t *a)
766{
767 byte data[64];
768 int i;
769 dword len = sizeof(data);
770 volatile byte __iomem *config;
771 volatile byte __iomem *flash;
772 byte c;
773
774/*
775 * First set some GT6401x config registers before accessing the BOOT-ROM
776 */
777 config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
778 c = READ_BYTE(&config[0xc3c]);
779 if (!(c & 0x08)) {
780 WRITE_BYTE(&config[0xc3c], c); /* Base Address enable register */
781 }
782 WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
783 WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
784 DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
785/*
786 * Read only the last 64 bytes of manufacturing data
787 */
788 memset(data, '\0', len);
789 flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
790 for (i = 0; i < len; i++) {
791 data[i] = READ_BYTE(&flash[0x8000 - len + i]);
792 }
793 DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
794
795 config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
796 WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC); /* Disable FLASH EPROM access */
797 WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
798 DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
799
800 if (memcmp(&data[48], "DIVAserverPR", 12)) {
801#if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND) /* { */
802 word cmd = 0, cmd_org;
803 void *addr;
804 dword addr1, addr3, addr4;
805 byte Bus, Slot;
806 void *hdev;
807 addr4 = a->resources.pci.bar[4];
808 addr3 = a->resources.pci.bar[3]; /* flash */
809 addr1 = a->resources.pci.bar[1]; /* unused */
810
811 DBG_ERR(("A: apply Compaq BIOS workaround"))
812 DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
813 data[0], data[1], data[2], data[3],
814 data[4], data[5], data[6], data[7]))
815
816 Bus = a->resources.pci.bus;
817 Slot = a->resources.pci.func;
818 hdev = a->resources.pci.hdev;
819 PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
820 PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
821
822 PCIwrite(Bus, Slot, 0x14, &addr4, sizeof(addr4), hdev);
823 PCIwrite(Bus, Slot, 0x20, &addr1, sizeof(addr1), hdev);
824
825 PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
826
827 addr = a->resources.pci.addr[1];
828 a->resources.pci.addr[1] = a->resources.pci.addr[4];
829 a->resources.pci.addr[4] = addr;
830
831 addr1 = a->resources.pci.bar[1];
832 a->resources.pci.bar[1] = a->resources.pci.bar[4];
833 a->resources.pci.bar[4] = addr1;
834
835 /*
836 Try to read Flash again
837 */
838 len = sizeof(data);
839
840 config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
841 if (!(config[0xc3c] & 0x08)) {
842 config[0xc3c] |= 0x08; /* Base Address enable register */
843 }
844 config[LOW_BOOTCS_DREG] = 0x00;
845 config[HI_BOOTCS_DREG] = 0xFF;
846 DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
847
848 memset(data, '\0', len);
849 flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
850 for (i = 0; i < len; i++) {
851 data[i] = flash[0x8000 - len + i];
852 }
853 DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
854 config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
855 config[LOW_BOOTCS_DREG] = 0xFC;
856 config[HI_BOOTCS_DREG] = 0xFF;
857 DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
858
859 if (memcmp(&data[48], "DIVAserverPR", 12)) {
860 DBG_ERR(("A: failed to read serial number"))
861 DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
862 data[0], data[1], data[2], data[3],
863 data[4], data[5], data[6], data[7]))
864 return (-1);
865 }
866#else /* } { */
867 DBG_ERR(("A: failed to read DIVA signature word"))
868 DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
869 data[0], data[1], data[2], data[3],
870 data[4], data[5], data[6], data[7]))
871 DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
872 data[45], data[44]))
873#endif /* } */
874 }
875
876 a->xdi_adapter.serialNo =
877 (data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
878 data[44];
879 if (!a->xdi_adapter.serialNo
880 || (a->xdi_adapter.serialNo == 0xffffffff)) {
881 a->xdi_adapter.serialNo = 0;
882 DBG_ERR(("A: failed to read serial number"))
883 return (-1);
884 }
885
886 DBG_LOG(("Serial No. : %ld", a->xdi_adapter.serialNo))
887 DBG_TRC(("Board Revision : %d.%02d", (int) data[41],
888 (int) data[40]))
889 DBG_TRC(("PLD revision : %d.%02d", (int) data[33],
890 (int) data[32]))
891 DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
892 (int) data[36]))
893
894 DBG_TRC(("Manufacturing Date : %d/%02d/%02d (yyyy/mm/dd)",
895 (int) ((data[28] > 90) ? 1900 : 2000) +
896 (int) data[28], (int) data[29], (int) data[30]))
897
898 return (0);
899}
900
901void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
902{
903}
904
905void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
906{
907}
908
909/*
910** Checks presence of DSP on board
911*/
912static int
913dsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp)
914{
915 word pattern;
916
917 WRITE_WORD(addr, 0x4000);
918 WRITE_WORD(data, DSP_SIGNATURE_PROBE_WORD);
919
920 WRITE_WORD(addr, 0x4000);
921 pattern = READ_WORD(data);
922
923 if (pattern != DSP_SIGNATURE_PROBE_WORD) {
924 DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
925 dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
926 return (-1);
927 }
928
929 WRITE_WORD(addr, 0x4000);
930 WRITE_WORD(data, ~DSP_SIGNATURE_PROBE_WORD);
931
932 WRITE_WORD(addr, 0x4000);
933 pattern = READ_WORD(data);
934
935 if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
936 DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
937 dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
938 return (-2);
939 }
940
941 DBG_TRC(("DSP[%d] present", dsp))
942
943 return (0);
944}
945
946
947/*
948** Check if DSP's are present and operating
949** Information about detected DSP's is returned as bit mask
950** Bit 0 - DSP1
951** ...
952** ...
953** ...
954** Bit 29 - DSP30
955*/
956static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a)
957{
958 byte __iomem *base;
959 byte __iomem *p;
960 dword ret = 0;
961 dword row_offset[7] = {
962 0x00000000,
963 0x00000800, /* 1 - ROW 1 */
964 0x00000840, /* 2 - ROW 2 */
965 0x00001000, /* 3 - ROW 3 */
966 0x00001040, /* 4 - ROW 4 */
967 0x00000000 /* 5 - ROW 0 */
968 };
969
970 byte __iomem *dsp_addr_port;
971 byte __iomem *dsp_data_port;
972 byte row_state;
973 int dsp_row = 0, dsp_index, dsp_num;
974
975 if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
976 return (0);
977 }
978
979 p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
980 WRITE_BYTE(p, _MP_RISC_RESET | _MP_DSP_RESET);
981 DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
982 diva_os_wait(5);
983
984 base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
985
986 for (dsp_num = 0; dsp_num < 30; dsp_num++) {
987 dsp_row = dsp_num / 7 + 1;
988 dsp_index = dsp_num % 7;
989
990 dsp_data_port = base;
991 dsp_addr_port = base;
992
993 dsp_data_port += row_offset[dsp_row];
994 dsp_addr_port += row_offset[dsp_row];
995
996 dsp_data_port += (dsp_index * 8);
997 dsp_addr_port += (dsp_index * 8) + 0x80;
998
999 if (!dsp_check_presence
1000 (dsp_addr_port, dsp_data_port, dsp_num + 1)) {
1001 ret |= (1 << dsp_num);
1002 }
1003 }
1004 DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
1005
1006 p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
1007 WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
1008 DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
1009 diva_os_wait(5);
1010
1011 /*
1012 Verify modules
1013 */
1014 for (dsp_row = 0; dsp_row < 4; dsp_row++) {
1015 row_state = ((ret >> (dsp_row * 7)) & 0x7F);
1016 if (row_state && (row_state != 0x7F)) {
1017 for (dsp_index = 0; dsp_index < 7; dsp_index++) {
1018 if (!(row_state & (1 << dsp_index))) {
1019 DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
1020 dsp_row + 1,
1021 dsp_index + 1))
1022 }
1023 }
1024 }
1025 }
1026
1027 if (!(ret & 0x10000000)) {
1028 DBG_ERR(("A: ON BOARD-DSP[1] failed"))
1029 }
1030 if (!(ret & 0x20000000)) {
1031 DBG_ERR(("A: ON BOARD-DSP[2] failed"))
1032 }
1033
1034 /*
1035 Print module population now
1036 */
1037 DBG_LOG(("+-----------------------+"))
1038 DBG_LOG(("| DSP MODULE POPULATION |"))
1039 DBG_LOG(("+-----------------------+"))
1040 DBG_LOG(("| 1 | 2 | 3 | 4 |"))
1041 DBG_LOG(("+-----------------------+"))
1042 DBG_LOG(("| %s | %s | %s | %s |",
1043 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
1044 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
1045 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
1046 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
1047 DBG_LOG(("+-----------------------+"))
1048
1049 DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
1050 ~ret & 0x3fffffff))
1051
1052 return (ret);
1053}
diff --git a/drivers/isdn/hardware/eicon/os_pri.h b/drivers/isdn/hardware/eicon/os_pri.h
deleted file mode 100644
index 0e91855b171a..000000000000
--- a/drivers/isdn/hardware/eicon/os_pri.h
+++ /dev/null
@@ -1,9 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: os_pri.h,v 1.1.2.2 2001/02/08 12:25:44 armin Exp $ */
3
4#ifndef __DIVA_OS_PRI_REV_1_H__
5#define __DIVA_OS_PRI_REV_1_H__
6
7int diva_pri_init_card(diva_os_xdi_adapter_t *a);
8
9#endif
diff --git a/drivers/isdn/hardware/eicon/pc.h b/drivers/isdn/hardware/eicon/pc.h
deleted file mode 100644
index 329c0c26abfb..000000000000
--- a/drivers/isdn/hardware/eicon/pc.h
+++ /dev/null
@@ -1,738 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef PC_H_INCLUDED /* { */
27#define PC_H_INCLUDED
28/*------------------------------------------------------------------*/
29/* buffer definition */
30/*------------------------------------------------------------------*/
31typedef struct {
32 word length; /* length of data/parameter field */
33 byte P[270]; /* data/parameter field */
34} PBUFFER;
35/*------------------------------------------------------------------*/
36/* dual port ram structure */
37/*------------------------------------------------------------------*/
38struct dual
39{
40 byte Req; /* request register */
41 byte ReqId; /* request task/entity identification */
42 byte Rc; /* return code register */
43 byte RcId; /* return code task/entity identification */
44 byte Ind; /* Indication register */
45 byte IndId; /* Indication task/entity identification */
46 byte IMask; /* Interrupt Mask Flag */
47 byte RNR; /* Receiver Not Ready (set by PC) */
48 byte XLock; /* XBuffer locked Flag */
49 byte Int; /* ISDN-S interrupt */
50 byte ReqCh; /* Channel field for layer-3 Requests */
51 byte RcCh; /* Channel field for layer-3 Returncodes */
52 byte IndCh; /* Channel field for layer-3 Indications */
53 byte MInd; /* more data indication field */
54 word MLength; /* more data total packet length */
55 byte ReadyInt; /* request field for ready interrupt */
56 byte SWReg; /* Software register for special purposes */
57 byte Reserved[11]; /* reserved space */
58 byte InterfaceType; /* interface type 1=16K interface */
59 word Signature; /* ISDN-S adapter Signature (GD) */
60 PBUFFER XBuffer; /* Transmit Buffer */
61 PBUFFER RBuffer; /* Receive Buffer */
62};
63/*------------------------------------------------------------------*/
64/* SWReg Values (0 means no command) */
65/*------------------------------------------------------------------*/
66#define SWREG_DIE_WITH_LEDON 0x01
67#define SWREG_HALT_CPU 0x02 /* Push CPU into a while (1) loop */
68/*------------------------------------------------------------------*/
69/* Id Fields Coding */
70/*------------------------------------------------------------------*/
71#define ID_MASK 0xe0 /* Mask for the ID field */
72#define GL_ERR_ID 0x1f /* ID for error reporting on global requests*/
73#define DSIG_ID 0x00 /* ID for D-channel signaling */
74#define NL_ID 0x20 /* ID for network-layer access (B or D) */
75#define BLLC_ID 0x60 /* ID for B-channel link level access */
76#define TASK_ID 0x80 /* ID for dynamic user tasks */
77#define TIMER_ID 0xa0 /* ID for timer task */
78#define TEL_ID 0xc0 /* ID for telephone support */
79#define MAN_ID 0xe0 /* ID for management */
80/*------------------------------------------------------------------*/
81/* ASSIGN and REMOVE requests are the same for all entities */
82/*------------------------------------------------------------------*/
83#define ASSIGN 0x01
84#define UREMOVE 0xfe /* without return code */
85#define REMOVE 0xff
86/*------------------------------------------------------------------*/
87/* Timer Interrupt Task Interface */
88/*------------------------------------------------------------------*/
89#define ASSIGN_TIM 0x01
90#define REMOVE_TIM 0xff
91/*------------------------------------------------------------------*/
92/* dynamic user task interface */
93/*------------------------------------------------------------------*/
94#define ASSIGN_TSK 0x01
95#define REMOVE_TSK 0xff
96#define LOAD 0xf0
97#define RELOCATE 0xf1
98#define START 0xf2
99#define LOAD2 0xf3
100#define RELOCATE2 0xf4
101/*------------------------------------------------------------------*/
102/* dynamic user task messages */
103/*------------------------------------------------------------------*/
104#define TSK_B2 0x0000
105#define TSK_WAKEUP 0x2000
106#define TSK_TIMER 0x4000
107#define TSK_TSK 0x6000
108#define TSK_PC 0xe000
109/*------------------------------------------------------------------*/
110/* LL management primitives */
111/*------------------------------------------------------------------*/
112#define ASSIGN_LL 1 /* assign logical link */
113#define REMOVE_LL 0xff /* remove logical link */
114/*------------------------------------------------------------------*/
115/* LL service primitives */
116/*------------------------------------------------------------------*/
117#define LL_UDATA 1 /* link unit data request/indication */
118#define LL_ESTABLISH 2 /* link establish request/indication */
119#define LL_RELEASE 3 /* link release request/indication */
120#define LL_DATA 4 /* data request/indication */
121#define LL_LOCAL 5 /* switch to local operation (COM only) */
122#define LL_DATA_PEND 5 /* data pending indication (SDLC SHM only) */
123#define LL_REMOTE 6 /* switch to remote operation (COM only) */
124#define LL_TEST 8 /* link test request */
125#define LL_MDATA 9 /* more data request/indication */
126#define LL_BUDATA 10 /* broadcast unit data request/indication */
127#define LL_XID 12 /* XID command request/indication */
128#define LL_XID_R 13 /* XID response request/indication */
129/*------------------------------------------------------------------*/
130/* NL service primitives */
131/*------------------------------------------------------------------*/
132#define N_MDATA 1 /* more data to come REQ/IND */
133#define N_CONNECT 2 /* OSI N-CONNECT REQ/IND */
134#define N_CONNECT_ACK 3 /* OSI N-CONNECT CON/RES */
135#define N_DISC 4 /* OSI N-DISC REQ/IND */
136#define N_DISC_ACK 5 /* OSI N-DISC CON/RES */
137#define N_RESET 6 /* OSI N-RESET REQ/IND */
138#define N_RESET_ACK 7 /* OSI N-RESET CON/RES */
139#define N_DATA 8 /* OSI N-DATA REQ/IND */
140#define N_EDATA 9 /* OSI N-EXPEDITED DATA REQ/IND */
141#define N_UDATA 10 /* OSI D-UNIT-DATA REQ/IND */
142#define N_BDATA 11 /* BROADCAST-DATA REQ/IND */
143#define N_DATA_ACK 12 /* data ack ind for D-bit procedure */
144#define N_EDATA_ACK 13 /* data ack ind for INTERRUPT */
145#define N_XON 15 /* clear RNR state */
146#define N_COMBI_IND N_XON /* combined indication */
147#define N_Q_BIT 0x10 /* Q-bit for req/ind */
148#define N_M_BIT 0x20 /* M-bit for req/ind */
149#define N_D_BIT 0x40 /* D-bit for req/ind */
150/*------------------------------------------------------------------*/
151/* Signaling management primitives */
152/*------------------------------------------------------------------*/
153#define ASSIGN_SIG 1 /* assign signaling task */
154#define UREMOVE_SIG 0xfe /* remove signaling task without return code*/
155#define REMOVE_SIG 0xff /* remove signaling task */
156/*------------------------------------------------------------------*/
157/* Signaling service primitives */
158/*------------------------------------------------------------------*/
159#define CALL_REQ 1 /* call request */
160#define CALL_CON 1 /* call confirmation */
161#define CALL_IND 2 /* incoming call connected */
162#define LISTEN_REQ 2 /* listen request */
163#define HANGUP 3 /* hangup request/indication */
164#define SUSPEND 4 /* call suspend request/confirm */
165#define RESUME 5 /* call resume request/confirm */
166#define SUSPEND_REJ 6 /* suspend rejected indication */
167#define USER_DATA 8 /* user data for user to user signaling */
168#define CONGESTION 9 /* network congestion indication */
169#define INDICATE_REQ 10 /* request to indicate an incoming call */
170#define INDICATE_IND 10 /* indicates that there is an incoming call */
171#define CALL_RES 11 /* accept an incoming call */
172#define CALL_ALERT 12 /* send ALERT for incoming call */
173#define INFO_REQ 13 /* INFO request */
174#define INFO_IND 13 /* INFO indication */
175#define REJECT 14 /* reject an incoming call */
176#define RESOURCES 15 /* reserve B-Channel hardware resources */
177#define HW_CTRL 16 /* B-Channel hardware IOCTL req/ind */
178#define TEL_CTRL 16 /* Telephone control request/indication */
179#define STATUS_REQ 17 /* Request D-State (returned in INFO_IND) */
180#define FAC_REG_REQ 18 /* 1TR6 connection independent fac reg */
181#define FAC_REG_ACK 19 /* 1TR6 fac registration acknowledge */
182#define FAC_REG_REJ 20 /* 1TR6 fac registration reject */
183#define CALL_COMPLETE 21/* send a CALL_PROC for incoming call */
184#define SW_CTRL 22 /* extended software features */
185#define REGISTER_REQ 23 /* Q.931 connection independent reg req */
186#define REGISTER_IND 24 /* Q.931 connection independent reg ind */
187#define FACILITY_REQ 25 /* Q.931 connection independent fac req */
188#define FACILITY_IND 26 /* Q.931 connection independent fac ind */
189#define NCR_INFO_REQ 27 /* INFO_REQ with NULL CR */
190#define GCR_MIM_REQ 28 /* MANAGEMENT_INFO_REQ with global CR */
191#define SIG_CTRL 29 /* Control for Signalling Hardware */
192#define DSP_CTRL 30 /* Control for DSPs */
193#define LAW_REQ 31 /* Law config request for (returns info_i) */
194#define SPID_CTRL 32 /* Request/indication SPID related */
195#define NCR_FACILITY 33 /* Request/indication with NULL/DUMMY CR */
196#define CALL_HOLD 34 /* Request/indication to hold a CALL */
197#define CALL_RETRIEVE 35 /* Request/indication to retrieve a CALL */
198#define CALL_HOLD_ACK 36 /* OK of hold a CALL */
199#define CALL_RETRIEVE_ACK 37 /* OK of retrieve a CALL */
200#define CALL_HOLD_REJ 38 /* Reject of hold a CALL */
201#define CALL_RETRIEVE_REJ 39 /* Reject of retrieve a call */
202#define GCR_RESTART 40 /* Send/Receive Restart message */
203#define S_SERVICE 41 /* Send/Receive Supplementary Service */
204#define S_SERVICE_REJ 42 /* Reject Supplementary Service indication */
205#define S_SUPPORTED 43 /* Req/Ind to get Supported Services */
206#define STATUS_ENQ 44 /* Req to send the D-ch request if !state0 */
207#define CALL_GUARD 45 /* Req/Ind to use the FLAGS_CALL_OUTCHECK */
208#define CALL_GUARD_HP 46 /* Call Guard function to reject a call */
209#define CALL_GUARD_IF 47 /* Call Guard function, inform the appl */
210#define SSEXT_REQ 48 /* Supplem.Serv./QSIG specific request */
211#define SSEXT_IND 49 /* Supplem.Serv./QSIG specific indication */
212/* reserved commands for the US protocols */
213#define INT_3PTY_NIND 50 /* US specific indication */
214#define INT_CF_NIND 51 /* US specific indication */
215#define INT_3PTY_DROP 52 /* US specific indication */
216#define INT_MOVE_CONF 53 /* US specific indication */
217#define INT_MOVE_RC 54 /* US specific indication */
218#define INT_MOVE_FLIPPED_CONF 55 /* US specific indication */
219#define INT_X5NI_OK 56 /* internal transfer OK indication */
220#define INT_XDMS_START 57 /* internal transfer OK indication */
221#define INT_XDMS_STOP 58 /* internal transfer finish indication */
222#define INT_XDMS_STOP2 59 /* internal transfer send FA */
223#define INT_CUSTCONF_REJ 60 /* internal conference reject */
224#define INT_CUSTXFER 61 /* internal transfer request */
225#define INT_CUSTX_NIND 62 /* internal transfer ack */
226#define INT_CUSTXREJ_NIND 63 /* internal transfer rej */
227#define INT_X5NI_CF_XFER 64 /* internal transfer OK indication */
228#define VSWITCH_REQ 65 /* communication between protocol and */
229#define VSWITCH_IND 66 /* capifunctions for D-CH-switching */
230#define MWI_POLL 67 /* Message Waiting Status Request fkt */
231#define CALL_PEND_NOTIFY 68 /* notify capi to set new listen */
232#define DO_NOTHING 69 /* dont do somethin if you get this */
233#define INT_CT_REJ 70 /* ECT rejected internal command */
234#define CALL_HOLD_COMPLETE 71 /* In NT Mode indicate hold complete */
235#define CALL_RETRIEVE_COMPLETE 72 /* In NT Mode indicate retrieve complete */
236/*------------------------------------------------------------------*/
237/* management service primitives */
238/*------------------------------------------------------------------*/
239#define MAN_READ 2
240#define MAN_WRITE 3
241#define MAN_EXECUTE 4
242#define MAN_EVENT_ON 5
243#define MAN_EVENT_OFF 6
244#define MAN_LOCK 7
245#define MAN_UNLOCK 8
246#define MAN_INFO_IND 2
247#define MAN_EVENT_IND 3
248#define MAN_TRACE_IND 4
249#define MAN_COMBI_IND 9
250#define MAN_ESC 0x80
251/*------------------------------------------------------------------*/
252/* return code coding */
253/*------------------------------------------------------------------*/
254#define UNKNOWN_COMMAND 0x01 /* unknown command */
255#define WRONG_COMMAND 0x02 /* wrong command */
256#define WRONG_ID 0x03 /* unknown task/entity id */
257#define WRONG_CH 0x04 /* wrong task/entity id */
258#define UNKNOWN_IE 0x05 /* unknown information el. */
259#define WRONG_IE 0x06 /* wrong information el. */
260#define OUT_OF_RESOURCES 0x07 /* ISDN-S card out of res. */
261#define ISDN_GUARD_REJ 0x09 /* ISDN-Guard SuppServ rej */
262#define N_FLOW_CONTROL 0x10 /* Flow-Control, retry */
263#define ASSIGN_RC 0xe0 /* ASSIGN acknowledgement */
264#define ASSIGN_OK 0xef /* ASSIGN OK */
265#define OK_FC 0xfc /* Flow-Control RC */
266#define READY_INT 0xfd /* Ready interrupt */
267#define TIMER_INT 0xfe /* timer interrupt */
268#define OK 0xff /* command accepted */
269/*------------------------------------------------------------------*/
270/* information elements */
271/*------------------------------------------------------------------*/
272#define SHIFT 0x90 /* codeset shift */
273#define MORE 0xa0 /* more data */
274#define SDNCMPL 0xa1 /* sending complete */
275#define CL 0xb0 /* congestion level */
276/* codeset 0 */
277#define SMSG 0x00 /* segmented message */
278#define BC 0x04 /* Bearer Capability */
279#define CAU 0x08 /* cause */
280#define CAD 0x0c /* Connected address */
281#define CAI 0x10 /* call identity */
282#define CHI 0x18 /* channel identification */
283#define LLI 0x19 /* logical link id */
284#define CHA 0x1a /* charge advice */
285#define FTY 0x1c /* Facility */
286#define DT 0x29 /* ETSI date/time */
287#define KEY 0x2c /* keypad information element */
288#define UID 0x2d /* User id information element */
289#define DSP 0x28 /* display */
290#define SIG 0x34 /* signalling hardware control */
291#define OAD 0x6c /* origination address */
292#define OSA 0x6d /* origination sub-address */
293#define CPN 0x70 /* called party number */
294#define DSA 0x71 /* destination sub-address */
295#define RDX 0x73 /* redirecting number extended */
296#define RDN 0x74 /* redirecting number */
297#define RIN 0x76 /* redirection number */
298#define IUP 0x76 /* VN6 rerouter->PCS (codeset 6) */
299#define IPU 0x77 /* VN6 PCS->rerouter (codeset 6) */
300#define RI 0x79 /* restart indicator */
301#define MIE 0x7a /* management info element */
302#define LLC 0x7c /* low layer compatibility */
303#define HLC 0x7d /* high layer compatibility */
304#define UUI 0x7e /* user user information */
305#define ESC 0x7f /* escape extension */
306#define DLC 0x20 /* data link layer configuration */
307#define NLC 0x21 /* network layer configuration */
308#define REDIRECT_IE 0x22 /* redirection request/indication data */
309#define REDIRECT_NET_IE 0x23 /* redirection network override data */
310/* codeset 6 */
311#define SIN 0x01 /* service indicator */
312#define CIF 0x02 /* charging information */
313#define DATE 0x03 /* date */
314#define CPS 0x07 /* called party status */
315/*------------------------------------------------------------------*/
316/* ESC information elements */
317/*------------------------------------------------------------------*/
318#define MSGTYPEIE 0x7a /* Messagetype info element */
319#define CRIE 0x7b /* INFO info element */
320#define CODESET6IE 0xec /* Tunnel for Codeset 6 IEs */
321#define VSWITCHIE 0xed /* VSwitch info element */
322#define SSEXTIE 0xee /* Supplem. Service info element */
323#define PROFILEIE 0xef /* Profile info element */
324/*------------------------------------------------------------------*/
325/* TEL_CTRL contents */
326/*------------------------------------------------------------------*/
327#define RING_ON 0x01
328#define RING_OFF 0x02
329#define HANDS_FREE_ON 0x03
330#define HANDS_FREE_OFF 0x04
331#define ON_HOOK 0x80
332#define OFF_HOOK 0x90
333/* operation values used by ETSI supplementary services */
334#define THREE_PTY_BEGIN 0x04
335#define THREE_PTY_END 0x05
336#define ECT_EXECUTE 0x06
337#define ACTIVATION_DIVERSION 0x07
338#define DEACTIVATION_DIVERSION 0x08
339#define CALL_DEFLECTION 0x0D
340#define INTERROGATION_DIVERSION 0x0B
341#define INTERROGATION_SERV_USR_NR 0x11
342#define ACTIVATION_MWI 0x20
343#define DEACTIVATION_MWI 0x21
344#define MWI_INDICATION 0x22
345#define MWI_RESPONSE 0x23
346#define CONF_BEGIN 0x28
347#define CONF_ADD 0x29
348#define CONF_SPLIT 0x2a
349#define CONF_DROP 0x2b
350#define CONF_ISOLATE 0x2c
351#define CONF_REATTACH 0x2d
352#define CONF_PARTYDISC 0x2e
353#define CCBS_INFO_RETAIN 0x2f
354#define CCBS_ERASECALLLINKAGEID 0x30
355#define CCBS_STOP_ALERTING 0x31
356#define CCBS_REQUEST 0x32
357#define CCBS_DEACTIVATE 0x33
358#define CCBS_INTERROGATE 0x34
359#define CCBS_STATUS 0x35
360#define CCBS_ERASE 0x36
361#define CCBS_B_FREE 0x37
362#define CCNR_INFO_RETAIN 0x38
363#define CCBS_REMOTE_USER_FREE 0x39
364#define CCNR_REQUEST 0x3a
365#define CCNR_INTERROGATE 0x3b
366#define GET_SUPPORTED_SERVICES 0xff
367#define DIVERSION_PROCEDURE_CFU 0x70
368#define DIVERSION_PROCEDURE_CFB 0x71
369#define DIVERSION_PROCEDURE_CFNR 0x72
370#define DIVERSION_DEACTIVATION_CFU 0x80
371#define DIVERSION_DEACTIVATION_CFB 0x81
372#define DIVERSION_DEACTIVATION_CFNR 0x82
373#define DIVERSION_INTERROGATE_NUM 0x11
374#define DIVERSION_INTERROGATE_CFU 0x60
375#define DIVERSION_INTERROGATE_CFB 0x61
376#define DIVERSION_INTERROGATE_CFNR 0x62
377/* Service Masks */
378#define SMASK_HOLD_RETRIEVE 0x00000001
379#define SMASK_TERMINAL_PORTABILITY 0x00000002
380#define SMASK_ECT 0x00000004
381#define SMASK_3PTY 0x00000008
382#define SMASK_CALL_FORWARDING 0x00000010
383#define SMASK_CALL_DEFLECTION 0x00000020
384#define SMASK_MCID 0x00000040
385#define SMASK_CCBS 0x00000080
386#define SMASK_MWI 0x00000100
387#define SMASK_CCNR 0x00000200
388#define SMASK_CONF 0x00000400
389/* ----------------------------------------------
390 Types of transfers used to transfer the
391 information in the 'struct RC->Reserved2[8]'
392 The information is transferred as 2 dwords
393 (2 4Byte unsigned values)
394 First of them is the transfer type.
395 2^32-1 possible messages are possible in this way.
396 The context of the second one had no meaning
397 ---------------------------------------------- */
398#define DIVA_RC_TYPE_NONE 0x00000000
399#define DIVA_RC_TYPE_REMOVE_COMPLETE 0x00000008
400#define DIVA_RC_TYPE_STREAM_PTR 0x00000009
401#define DIVA_RC_TYPE_CMA_PTR 0x0000000a
402#define DIVA_RC_TYPE_OK_FC 0x0000000b
403#define DIVA_RC_TYPE_RX_DMA 0x0000000c
404/* ------------------------------------------------------
405 IO Control codes for IN BAND SIGNALING
406 ------------------------------------------------------ */
407#define CTRL_L1_SET_SIG_ID 5
408#define CTRL_L1_SET_DAD 6
409#define CTRL_L1_RESOURCES 7
410/* ------------------------------------------------------ */
411/* ------------------------------------------------------
412 Layer 2 types
413 ------------------------------------------------------ */
414#define X75T 1 /* x.75 for ttx */
415#define TRF 2 /* transparent with hdlc framing */
416#define TRF_IN 3 /* transparent with hdlc fr. inc. */
417#define SDLC 4 /* sdlc, sna layer-2 */
418#define X75 5 /* x.75 for btx */
419#define LAPD 6 /* lapd (Q.921) */
420#define X25_L2 7 /* x.25 layer-2 */
421#define V120_L2 8 /* V.120 layer-2 protocol */
422#define V42_IN 9 /* V.42 layer-2 protocol, incoming */
423#define V42 10 /* V.42 layer-2 protocol */
424#define MDM_ATP 11 /* AT Parser built in the L2 */
425#define X75_V42BIS 12 /* x.75 with V.42bis */
426#define RTPL2_IN 13 /* RTP layer-2 protocol, incoming */
427#define RTPL2 14 /* RTP layer-2 protocol */
428#define V120_V42BIS 15 /* V.120 asynchronous mode supporting V.42bis compression */
429#define LISTENER 27 /* Layer 2 to listen line */
430#define MTP2 28 /* MTP2 Layer 2 */
431#define PIAFS_CRC 29 /* PIAFS Layer 2 with CRC calculation at L2 */
432/* ------------------------------------------------------
433 PIAFS DLC DEFINITIONS
434 ------------------------------------------------------ */
435#define PIAFS_64K 0x01
436#define PIAFS_VARIABLE_SPEED 0x02
437#define PIAFS_CHINESE_SPEED 0x04
438#define PIAFS_UDATA_ABILITY_ID 0x80
439#define PIAFS_UDATA_ABILITY_DCDON 0x01
440#define PIAFS_UDATA_ABILITY_DDI 0x80
441/*
442 DLC of PIAFS :
443 Byte | 8 7 6 5 4 3 2 1
444 -----+--------------------------------------------------------
445 0 | 0 0 1 0 0 0 0 0 Data Link Configuration
446 1 | X X X X X X X X Length of IE (at least 15 Bytes)
447 2 | 0 0 0 0 0 0 0 0 max. information field, LOW byte (not used, fix 73 Bytes)
448 3 | 0 0 0 0 0 0 0 0 max. information field, HIGH byte (not used, fix 73 Bytes)
449 4 | 0 0 0 0 0 0 0 0 address A (not used)
450 5 | 0 0 0 0 0 0 0 0 address B (not used)
451 6 | 0 0 0 0 0 0 0 0 Mode (not used, fix 128)
452 7 | 0 0 0 0 0 0 0 0 Window Size (not used, fix 127)
453 8 | X X X X X X X X XID Length, Low Byte (at least 7 Bytes)
454 9 | X X X X X X X X XID Length, High Byte
455 10 | 0 0 0 0 0 C V S PIAFS Protocol Speed configuration -> Note(1)
456 | S = 0 -> Protocol Speed is 32K
457 | S = 1 -> Protocol Speed is 64K
458 | V = 0 -> Protocol Speed is fixed
459 | V = 1 -> Protocol Speed is variable
460 | C = 0 -> speed setting according to standard
461 | C = 1 -> speed setting for chinese implementation
462 11 | 0 0 0 0 0 0 R T P0 - V42bis Compression enable/disable, Low Byte
463 | T = 0 -> Transmit Direction enable
464 | T = 1 -> Transmit Direction disable
465 | R = 0 -> Receive Direction enable
466 | R = 1 -> Receive Direction disable
467 13 | 0 0 0 0 0 0 0 0 P0 - V42bis Compression enable/disable, High Byte
468 14 | X X X X X X X X P1 - V42bis Dictionary Size, Low Byte
469 15 | X X X X X X X X P1 - V42bis Dictionary Size, High Byte
470 16 | X X X X X X X X P2 - V42bis String Length, Low Byte
471 17 | X X X X X X X X P2 - V42bis String Length, High Byte
472 18 | X X X X X X X X PIAFS extension length
473 19 | 1 0 0 0 0 0 0 0 PIAFS extension Id (0x80) - UDATA abilities
474 20 | U 0 0 0 0 0 0 D UDATA abilities -> Note (2)
475 | up to now the following Bits are defined:
476 | D - signal DCD ON
477 | U - use extensive UDATA control communication
478 | for DDI test application
479 + Note (1): ----------+------+-----------------------------------------+
480 | PIAFS Protocol | Bit | |
481 | Speed configuration | S | Bit 1 - Protocol Speed |
482 | | | 0 - 32K |
483 | | | 1 - 64K (default) |
484 | | V | Bit 2 - Variable Protocol Speed |
485 | | | 0 - Speed is fix |
486 | | | 1 - Speed is variable (default) |
487 | | | OVERWRITES 32k Bit 1 |
488 | | C | Bit 3 0 - Speed Settings according to |
489 | | | PIAFS specification |
490 | | | 1 - Speed setting for chinese |
491 | | | PIAFS implementation |
492 | | | Explanation for chinese speed settings: |
493 | | | if Bit 3 is set the following |
494 | | | rules apply: |
495 | | | Bit1=0 Bit2=0: 32k fix |
496 | | | Bit1=1 Bit2=0: 64k fix |
497 | | | Bit1=0 Bit2=1: PIAFS is trying |
498 | | | to negotiate 32k is that is |
499 | | | not possible it tries to |
500 | | | negotiate 64k |
501 | | | Bit1=1 Bit2=1: PIAFS is trying |
502 | | | to negotiate 64k is that is |
503 | | | not possible it tries to |
504 | | | negotiate 32k |
505 + Note (2): ----------+------+-----------------------------------------+
506 | PIAFS | Bit | this byte defines the usage of UDATA |
507 | Implementation | | control communication |
508 | UDATA usage | D | Bit 1 - DCD-ON signalling |
509 | | | 0 - no DCD-ON is signalled |
510 | | | (default) |
511 | | | 1 - DCD-ON will be signalled |
512 | | U | Bit 8 - DDI test application UDATA |
513 | | | control communication |
514 | | | 0 - no UDATA control |
515 | | | communication (default) |
516 | | | sets as well the DCD-ON |
517 | | | signalling |
518 | | | 1 - UDATA control communication |
519 | | | ATTENTION: Do not use these |
520 | | | setting if you |
521 | | | are not really |
522 | | | that you need it |
523 | | | and you know |
524 | | | exactly what you |
525 | | | are doing. |
526 | | | You can easily |
527 | | | disable any |
528 | | | data transfer. |
529 +---------------------+------+-----------------------------------------+
530*/
531/* ------------------------------------------------------
532 LISTENER DLC DEFINITIONS
533 ------------------------------------------------------ */
534#define LISTENER_FEATURE_MASK_CUMMULATIVE 0x0001
535/* ------------------------------------------------------
536 LISTENER META-FRAME CODE/PRIMITIVE DEFINITIONS
537 ------------------------------------------------------ */
538#define META_CODE_LL_UDATA_RX 0x01
539#define META_CODE_LL_UDATA_TX 0x02
540#define META_CODE_LL_DATA_RX 0x03
541#define META_CODE_LL_DATA_TX 0x04
542#define META_CODE_LL_MDATA_RX 0x05
543#define META_CODE_LL_MDATA_TX 0x06
544#define META_CODE_EMPTY 0x10
545#define META_CODE_LOST_FRAMES 0x11
546#define META_FLAG_TRUNCATED 0x0001
547/*------------------------------------------------------------------*/
548/* CAPI-like profile to indicate features on LAW_REQ */
549/*------------------------------------------------------------------*/
550#define GL_INTERNAL_CONTROLLER_SUPPORTED 0x00000001L
551#define GL_EXTERNAL_EQUIPMENT_SUPPORTED 0x00000002L
552#define GL_HANDSET_SUPPORTED 0x00000004L
553#define GL_DTMF_SUPPORTED 0x00000008L
554#define GL_SUPPLEMENTARY_SERVICES_SUPPORTED 0x00000010L
555#define GL_CHANNEL_ALLOCATION_SUPPORTED 0x00000020L
556#define GL_BCHANNEL_OPERATION_SUPPORTED 0x00000040L
557#define GL_LINE_INTERCONNECT_SUPPORTED 0x00000080L
558#define B1_HDLC_SUPPORTED 0x00000001L
559#define B1_TRANSPARENT_SUPPORTED 0x00000002L
560#define B1_V110_ASYNC_SUPPORTED 0x00000004L
561#define B1_V110_SYNC_SUPPORTED 0x00000008L
562#define B1_T30_SUPPORTED 0x00000010L
563#define B1_HDLC_INVERTED_SUPPORTED 0x00000020L
564#define B1_TRANSPARENT_R_SUPPORTED 0x00000040L
565#define B1_MODEM_ALL_NEGOTIATE_SUPPORTED 0x00000080L
566#define B1_MODEM_ASYNC_SUPPORTED 0x00000100L
567#define B1_MODEM_SYNC_HDLC_SUPPORTED 0x00000200L
568#define B2_X75_SUPPORTED 0x00000001L
569#define B2_TRANSPARENT_SUPPORTED 0x00000002L
570#define B2_SDLC_SUPPORTED 0x00000004L
571#define B2_LAPD_SUPPORTED 0x00000008L
572#define B2_T30_SUPPORTED 0x00000010L
573#define B2_PPP_SUPPORTED 0x00000020L
574#define B2_TRANSPARENT_NO_CRC_SUPPORTED 0x00000040L
575#define B2_MODEM_EC_COMPRESSION_SUPPORTED 0x00000080L
576#define B2_X75_V42BIS_SUPPORTED 0x00000100L
577#define B2_V120_ASYNC_SUPPORTED 0x00000200L
578#define B2_V120_ASYNC_V42BIS_SUPPORTED 0x00000400L
579#define B2_V120_BIT_TRANSPARENT_SUPPORTED 0x00000800L
580#define B2_LAPD_FREE_SAPI_SEL_SUPPORTED 0x00001000L
581#define B3_TRANSPARENT_SUPPORTED 0x00000001L
582#define B3_T90NL_SUPPORTED 0x00000002L
583#define B3_ISO8208_SUPPORTED 0x00000004L
584#define B3_X25_DCE_SUPPORTED 0x00000008L
585#define B3_T30_SUPPORTED 0x00000010L
586#define B3_T30_WITH_EXTENSIONS_SUPPORTED 0x00000020L
587#define B3_RESERVED_SUPPORTED 0x00000040L
588#define B3_MODEM_SUPPORTED 0x00000080L
589#define MANUFACTURER_FEATURE_SLAVE_CODEC 0x00000001L
590#define MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS 0x00000002L
591#define MANUFACTURER_FEATURE_HARDDTMF 0x00000004L
592#define MANUFACTURER_FEATURE_SOFTDTMF_SEND 0x00000008L
593#define MANUFACTURER_FEATURE_DTMF_PARAMETERS 0x00000010L
594#define MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE 0x00000020L
595#define MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD 0x00000040L
596#define MANUFACTURER_FEATURE_V18 0x00000080L
597#define MANUFACTURER_FEATURE_MIXER_CH_CH 0x00000100L
598#define MANUFACTURER_FEATURE_MIXER_CH_PC 0x00000200L
599#define MANUFACTURER_FEATURE_MIXER_PC_CH 0x00000400L
600#define MANUFACTURER_FEATURE_MIXER_PC_PC 0x00000800L
601#define MANUFACTURER_FEATURE_ECHO_CANCELLER 0x00001000L
602#define MANUFACTURER_FEATURE_RTP 0x00002000L
603#define MANUFACTURER_FEATURE_T38 0x00004000L
604#define MANUFACTURER_FEATURE_TRANSP_DELIVERY_CONF 0x00008000L
605#define MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL 0x00010000L
606#define MANUFACTURER_FEATURE_OOB_CHANNEL 0x00020000L
607#define MANUFACTURER_FEATURE_IN_BAND_CHANNEL 0x00040000L
608#define MANUFACTURER_FEATURE_IN_BAND_FEATURE 0x00080000L
609#define MANUFACTURER_FEATURE_PIAFS 0x00100000L
610#define MANUFACTURER_FEATURE_DTMF_TONE 0x00200000L
611#define MANUFACTURER_FEATURE_FAX_PAPER_FORMATS 0x00400000L
612#define MANUFACTURER_FEATURE_OK_FC_LABEL 0x00800000L
613#define MANUFACTURER_FEATURE_VOWN 0x01000000L
614#define MANUFACTURER_FEATURE_XCONNECT 0x02000000L
615#define MANUFACTURER_FEATURE_DMACONNECT 0x04000000L
616#define MANUFACTURER_FEATURE_AUDIO_TAP 0x08000000L
617#define MANUFACTURER_FEATURE_FAX_NONSTANDARD 0x10000000L
618#define MANUFACTURER_FEATURE_SS7 0x20000000L
619#define MANUFACTURER_FEATURE_MADAPTER 0x40000000L
620#define MANUFACTURER_FEATURE_MEASURE 0x80000000L
621#define MANUFACTURER_FEATURE2_LISTENING 0x00000001L
622#define MANUFACTURER_FEATURE2_SS_DIFFCONTPOSSIBLE 0x00000002L
623#define MANUFACTURER_FEATURE2_GENERIC_TONE 0x00000004L
624#define MANUFACTURER_FEATURE2_COLOR_FAX 0x00000008L
625#define MANUFACTURER_FEATURE2_SS_ECT_DIFFCONTPOSSIBLE 0x00000010L
626#define RTP_PRIM_PAYLOAD_PCMU_8000 0
627#define RTP_PRIM_PAYLOAD_1016_8000 1
628#define RTP_PRIM_PAYLOAD_G726_32_8000 2
629#define RTP_PRIM_PAYLOAD_GSM_8000 3
630#define RTP_PRIM_PAYLOAD_G723_8000 4
631#define RTP_PRIM_PAYLOAD_DVI4_8000 5
632#define RTP_PRIM_PAYLOAD_DVI4_16000 6
633#define RTP_PRIM_PAYLOAD_LPC_8000 7
634#define RTP_PRIM_PAYLOAD_PCMA_8000 8
635#define RTP_PRIM_PAYLOAD_G722_16000 9
636#define RTP_PRIM_PAYLOAD_QCELP_8000 12
637#define RTP_PRIM_PAYLOAD_G728_8000 14
638#define RTP_PRIM_PAYLOAD_G729_8000 18
639#define RTP_PRIM_PAYLOAD_GSM_HR_8000 30
640#define RTP_PRIM_PAYLOAD_GSM_EFR_8000 31
641#define RTP_ADD_PAYLOAD_BASE 32
642#define RTP_ADD_PAYLOAD_RED 32
643#define RTP_ADD_PAYLOAD_CN_8000 33
644#define RTP_ADD_PAYLOAD_DTMF 34
645#define RTP_PRIM_PAYLOAD_PCMU_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_PCMU_8000)
646#define RTP_PRIM_PAYLOAD_1016_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_1016_8000)
647#define RTP_PRIM_PAYLOAD_G726_32_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G726_32_8000)
648#define RTP_PRIM_PAYLOAD_GSM_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_GSM_8000)
649#define RTP_PRIM_PAYLOAD_G723_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G723_8000)
650#define RTP_PRIM_PAYLOAD_DVI4_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_DVI4_8000)
651#define RTP_PRIM_PAYLOAD_DVI4_16000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_DVI4_16000)
652#define RTP_PRIM_PAYLOAD_LPC_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_LPC_8000)
653#define RTP_PRIM_PAYLOAD_PCMA_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_PCMA_8000)
654#define RTP_PRIM_PAYLOAD_G722_16000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G722_16000)
655#define RTP_PRIM_PAYLOAD_QCELP_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_QCELP_8000)
656#define RTP_PRIM_PAYLOAD_G728_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G728_8000)
657#define RTP_PRIM_PAYLOAD_G729_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G729_8000)
658#define RTP_PRIM_PAYLOAD_GSM_HR_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_GSM_HR_8000)
659#define RTP_PRIM_PAYLOAD_GSM_EFR_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_GSM_EFR_8000)
660#define RTP_ADD_PAYLOAD_RED_SUPPORTED (1L << (RTP_ADD_PAYLOAD_RED - RTP_ADD_PAYLOAD_BASE))
661#define RTP_ADD_PAYLOAD_CN_8000_SUPPORTED (1L << (RTP_ADD_PAYLOAD_CN_8000 - RTP_ADD_PAYLOAD_BASE))
662#define RTP_ADD_PAYLOAD_DTMF_SUPPORTED (1L << (RTP_ADD_PAYLOAD_DTMF - RTP_ADD_PAYLOAD_BASE))
663/* virtual switching definitions */
664#define VSJOIN 1
665#define VSTRANSPORT 2
666#define VSGETPARAMS 3
667#define VSCAD 1
668#define VSRXCPNAME 2
669#define VSCALLSTAT 3
670#define VSINVOKEID 4
671#define VSCLMRKS 5
672#define VSTBCTIDENT 6
673#define VSETSILINKID 7
674#define VSSAMECONTROLLER 8
675/* Errorcodes for VSETSILINKID begin */
676#define VSETSILINKIDRRWC 1
677#define VSETSILINKIDREJECT 2
678#define VSETSILINKIDTIMEOUT 3
679#define VSETSILINKIDFAILCOUNT 4
680#define VSETSILINKIDERROR 5
681/* Errorcodes for VSETSILINKID end */
682/* -----------------------------------------------------------**
683** The PROTOCOL_FEATURE_STRING in feature.h (included **
684** in prstart.sx and astart.sx) defines capabilities and **
685** features of the actual protocol code. It's used as a bit **
686** mask. **
687** The following Bits are defined: **
688** -----------------------------------------------------------*/
689#define PROTCAP_TELINDUS 0x0001 /* Telindus Variant of protocol code */
690#define PROTCAP_MAN_IF 0x0002 /* Management interface implemented */
691#define PROTCAP_V_42 0x0004 /* V42 implemented */
692#define PROTCAP_V90D 0x0008 /* V.90D (implies up to 384k DSP code) */
693#define PROTCAP_EXTD_FAX 0x0010 /* Extended FAX (ECM, 2D, T6, Polling) */
694#define PROTCAP_EXTD_RXFC 0x0020 /* RxFC (Extd Flow Control), OOB Chnl */
695#define PROTCAP_VOIP 0x0040 /* VoIP (implies up to 512k DSP code) */
696#define PROTCAP_CMA_ALLPR 0x0080 /* CMA support for all NL primitives */
697#define PROTCAP_FREE8 0x0100 /* not used */
698#define PROTCAP_FREE9 0x0200 /* not used */
699#define PROTCAP_FREE10 0x0400 /* not used */
700#define PROTCAP_FREE11 0x0800 /* not used */
701#define PROTCAP_FREE12 0x1000 /* not used */
702#define PROTCAP_FREE13 0x2000 /* not used */
703#define PROTCAP_FREE14 0x4000 /* not used */
704#define PROTCAP_EXTENSION 0x8000 /* used for future extensions */
705/* -----------------------------------------------------------* */
706/* Onhook data transmission ETS30065901 */
707/* Message Type */
708/*#define RESERVED4 0x4*/
709#define CALL_SETUP 0x80
710#define MESSAGE_WAITING_INDICATOR 0x82
711/*#define RESERVED84 0x84*/
712/*#define RESERVED85 0x85*/
713#define ADVICE_OF_CHARGE 0x86
714/*1111 0001
715 to
716 1111 1111
717 F1H - Reserved for network operator use
718 to
719 FFH*/
720/* Parameter Types */
721#define DATE_AND_TIME 1
722#define CLI_PARAMETER_TYPE 2
723#define CALLED_DIRECTORY_NUMBER_PARAMETER_TYPE 3
724#define REASON_FOR_ABSENCE_OF_CLI_PARAMETER_TYPE 4
725#define NAME_PARAMETER_TYPE 7
726#define REASON_FOR_ABSENCE_OF_CALLING_PARTY_NAME_PARAMETER_TYPE 8
727#define VISUAL_INDICATOR_PARAMETER_TYPE 0xb
728#define COMPLEMENTARY_CLI_PARAMETER_TYPE 0x10
729#define CALL_TYPE_PARAMETER_TYPE 0x11
730#define FIRST_CALLED_LINE_DIRECTORY_NUMBER_PARAMETER_TYPE 0x12
731#define NETWORK_MESSAGE_SYSTEM_STATUS_PARAMETER_TYPE 0x13
732#define FORWARDED_CALL_TYPE_PARAMETER_TYPE 0x15
733#define TYPE_OF_CALLING_USER_PARAMETER_TYPE 0x16
734#define REDIRECTING_NUMBER_PARAMETER_TYPE 0x1a
735#define EXTENSION_FOR_NETWORK_OPERATOR_USE_PARAMETER_TYPE 0xe0
736/* -----------------------------------------------------------* */
737#else
738#endif /* PC_H_INCLUDED } */
diff --git a/drivers/isdn/hardware/eicon/pc_init.h b/drivers/isdn/hardware/eicon/pc_init.h
deleted file mode 100644
index d1d00866e8d4..000000000000
--- a/drivers/isdn/hardware/eicon/pc_init.h
+++ /dev/null
@@ -1,267 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef PC_INIT_H_
27#define PC_INIT_H_
28/*------------------------------------------------------------------*/
29/*
30 Initialisation parameters for the card
31 0x0008 <byte> TEI
32 0x0009 <byte> NT2 flag
33 0x000a <byte> Default DID length
34 0x000b <byte> Disable watchdog flag
35 0x000c <byte> Permanent connection flag
36 0x000d <byte> Bit 3-8: L1 Hunt Group/Tristate
37 0x000d <byte> Bit 1: QSig small CR length if set to 1
38 0x000d <byte> Bit 2: QSig small CHI length if set to 1
39 0x000e <byte> Bit 1-3: Stable L2, 0=OnDemand,1=NoDisc,2=permanent
40 0x000e <byte> Bit 4: NT mode
41 0x000e <byte> Bit 5: QSig Channel ID format
42 0x000e <byte> Bit 6: QSig Call Forwarding Allowed Flag
43 0x000e <byte> Bit 7: Disable AutoSPID Flag
44 0x000f <byte> No order check flag
45 0x0010 <byte> Force companding type:0=default,1=a-law,2=u-law
46 0x0012 <byte> Low channel flag
47 0x0013 <byte> Protocol version
48 0x0014 <byte> CRC4 option:0=default,1=double_frm,2=multi_frm,3=auto
49 0x0015 <byte> Bit 0: NoHscx30, Bit 1: Loopback flag, Bit 2: ForceHscx30
50 0x0016 <byte> DSP info
51 0x0017-0x0019 Serial number
52 0x001a <byte> Card type
53 0x0020 <string> OAD 0
54 0x0040 <string> OSA 0
55 0x0060 <string> SPID 0 (if not T.1)
56 0x0060 <struct> if T.1: Robbed Bit Configuration
57 0x0060 length (8)
58 0x0061 RBS Answer Delay
59 0x0062 RBS Config Bit 3, 4:
60 0 0 -> Wink Start
61 1 0 -> Loop Start
62 0 1 -> Ground Start
63 1 1 -> reserved
64 Bit 5, 6:
65 0 0 -> Pulse Dial -> Rotary
66 1 0 -> DTMF
67 0 1 -> MF
68 1 1 -> reserved
69 0x0063 RBS RX Digit Timeout
70 0x0064 RBS Bearer Capability
71 0x0065-0x0069 RBS Debug Mask
72 0x0080 <string> OAD 1
73 0x00a0 <string> OSA 1
74 0x00c0 <string> SPID 1
75 0x00e0 <w-element list> Additional configuration
76*/
77#define PCINIT_END_OF_LIST 0x00
78#define PCINIT_MODEM_GUARD_TONE 0x01
79#define PCINIT_MODEM_MIN_SPEED 0x02
80#define PCINIT_MODEM_MAX_SPEED 0x03
81#define PCINIT_MODEM_PROTOCOL_OPTIONS 0x04
82#define PCINIT_FAX_OPTIONS 0x05
83#define PCINIT_FAX_MAX_SPEED 0x06
84#define PCINIT_MODEM_OPTIONS 0x07
85#define PCINIT_MODEM_NEGOTIATION_MODE 0x08
86#define PCINIT_MODEM_MODULATIONS_MASK 0x09
87#define PCINIT_MODEM_TRANSMIT_LEVEL 0x0a
88#define PCINIT_FAX_DISABLED_RESOLUTIONS 0x0b
89#define PCINIT_FAX_MAX_RECORDING_WIDTH 0x0c
90#define PCINIT_FAX_MAX_RECORDING_LENGTH 0x0d
91#define PCINIT_FAX_MIN_SCANLINE_TIME 0x0e
92#define PCINIT_US_EKTS_CACH_HANDLES 0x0f
93#define PCINIT_US_EKTS_BEGIN_CONF 0x10
94#define PCINIT_US_EKTS_DROP_CONF 0x11
95#define PCINIT_US_EKTS_CALL_TRANSFER 0x12
96#define PCINIT_RINGERTONE_OPTION 0x13
97#define PCINIT_CARD_ADDRESS 0x14
98#define PCINIT_FPGA_FEATURES 0x15
99#define PCINIT_US_EKTS_MWI 0x16
100#define PCINIT_MODEM_SPEAKER_CONTROL 0x17
101#define PCINIT_MODEM_SPEAKER_VOLUME 0x18
102#define PCINIT_MODEM_CARRIER_WAIT_TIME 0x19
103#define PCINIT_MODEM_CARRIER_LOSS_TIME 0x1a
104#define PCINIT_UNCHAN_B_MASK 0x1b
105#define PCINIT_PART68_LIMITER 0x1c
106#define PCINIT_XDI_FEATURES 0x1d
107#define PCINIT_QSIG_DIALECT 0x1e
108#define PCINIT_DISABLE_AUTOSPID_FLAG 0x1f
109#define PCINIT_FORCE_VOICE_MAIL_ALERT 0x20
110#define PCINIT_PIAFS_TURNAROUND_FRAMES 0x21
111#define PCINIT_L2_COUNT 0x22
112#define PCINIT_QSIG_FEATURES 0x23
113#define PCINIT_NO_SIGNALLING 0x24
114#define PCINIT_CARD_SN 0x25
115#define PCINIT_CARD_PORT 0x26
116#define PCINIT_ALERTTO 0x27
117#define PCINIT_MODEM_EYE_SETUP 0x28
118#define PCINIT_FAX_V34_OPTIONS 0x29
119/*------------------------------------------------------------------*/
120#define PCINIT_MODEM_GUARD_TONE_NONE 0x00
121#define PCINIT_MODEM_GUARD_TONE_550HZ 0x01
122#define PCINIT_MODEM_GUARD_TONE_1800HZ 0x02
123#define PCINIT_MODEM_GUARD_TONE_CHOICES 0x03
124#define PCINIT_MODEMPROT_DISABLE_V42_V42BIS 0x0001
125#define PCINIT_MODEMPROT_DISABLE_MNP_MNP5 0x0002
126#define PCINIT_MODEMPROT_REQUIRE_PROTOCOL 0x0004
127#define PCINIT_MODEMPROT_DISABLE_V42_DETECT 0x0008
128#define PCINIT_MODEMPROT_DISABLE_COMPRESSION 0x0010
129#define PCINIT_MODEMPROT_REQUIRE_PROTOCOL_V34UP 0x0020
130#define PCINIT_MODEMPROT_NO_PROTOCOL_IF_1200 0x0100
131#define PCINIT_MODEMPROT_BUFFER_IN_V42_DETECT 0x0200
132#define PCINIT_MODEMPROT_DISABLE_V42_SREJ 0x0400
133#define PCINIT_MODEMPROT_DISABLE_MNP3 0x0800
134#define PCINIT_MODEMPROT_DISABLE_MNP4 0x1000
135#define PCINIT_MODEMPROT_DISABLE_MNP10 0x2000
136#define PCINIT_MODEMPROT_NO_PROTOCOL_IF_V22BIS 0x4000
137#define PCINIT_MODEMPROT_NO_PROTOCOL_IF_V32BIS 0x8000
138#define PCINIT_MODEMCONFIG_LEASED_LINE_MODE 0x00000001L
139#define PCINIT_MODEMCONFIG_4_WIRE_OPERATION 0x00000002L
140#define PCINIT_MODEMCONFIG_DISABLE_BUSY_DETECT 0x00000004L
141#define PCINIT_MODEMCONFIG_DISABLE_CALLING_TONE 0x00000008L
142#define PCINIT_MODEMCONFIG_DISABLE_ANSWER_TONE 0x00000010L
143#define PCINIT_MODEMCONFIG_ENABLE_DIAL_TONE_DET 0x00000020L
144#define PCINIT_MODEMCONFIG_USE_POTS_INTERFACE 0x00000040L
145#define PCINIT_MODEMCONFIG_FORCE_RAY_TAYLOR_FAX 0x00000080L
146#define PCINIT_MODEMCONFIG_DISABLE_RETRAIN 0x00000100L
147#define PCINIT_MODEMCONFIG_DISABLE_STEPDOWN 0x00000200L
148#define PCINIT_MODEMCONFIG_DISABLE_SPLIT_SPEED 0x00000400L
149#define PCINIT_MODEMCONFIG_DISABLE_TRELLIS 0x00000800L
150#define PCINIT_MODEMCONFIG_ALLOW_RDL_TEST_LOOP 0x00001000L
151#define PCINIT_MODEMCONFIG_DISABLE_STEPUP 0x00002000L
152#define PCINIT_MODEMCONFIG_DISABLE_FLUSH_TIMER 0x00004000L
153#define PCINIT_MODEMCONFIG_REVERSE_DIRECTION 0x00008000L
154#define PCINIT_MODEMCONFIG_DISABLE_TX_REDUCTION 0x00010000L
155#define PCINIT_MODEMCONFIG_DISABLE_PRECODING 0x00020000L
156#define PCINIT_MODEMCONFIG_DISABLE_PREEMPHASIS 0x00040000L
157#define PCINIT_MODEMCONFIG_DISABLE_SHAPING 0x00080000L
158#define PCINIT_MODEMCONFIG_DISABLE_NONLINEAR_EN 0x00100000L
159#define PCINIT_MODEMCONFIG_DISABLE_MANUALREDUCT 0x00200000L
160#define PCINIT_MODEMCONFIG_DISABLE_16_POINT_TRN 0x00400000L
161#define PCINIT_MODEMCONFIG_DISABLE_2400_SYMBOLS 0x01000000L
162#define PCINIT_MODEMCONFIG_DISABLE_2743_SYMBOLS 0x02000000L
163#define PCINIT_MODEMCONFIG_DISABLE_2800_SYMBOLS 0x04000000L
164#define PCINIT_MODEMCONFIG_DISABLE_3000_SYMBOLS 0x08000000L
165#define PCINIT_MODEMCONFIG_DISABLE_3200_SYMBOLS 0x10000000L
166#define PCINIT_MODEMCONFIG_DISABLE_3429_SYMBOLS 0x20000000L
167#define PCINIT_MODEM_NEGOTIATE_HIGHEST 0x00
168#define PCINIT_MODEM_NEGOTIATE_DISABLED 0x01
169#define PCINIT_MODEM_NEGOTIATE_IN_CLASS 0x02
170#define PCINIT_MODEM_NEGOTIATE_V100 0x03
171#define PCINIT_MODEM_NEGOTIATE_V8 0x04
172#define PCINIT_MODEM_NEGOTIATE_V8BIS 0x05
173#define PCINIT_MODEM_NEGOTIATE_CHOICES 0x06
174#define PCINIT_MODEMMODULATION_DISABLE_V21 0x00000001L
175#define PCINIT_MODEMMODULATION_DISABLE_V23 0x00000002L
176#define PCINIT_MODEMMODULATION_DISABLE_V22 0x00000004L
177#define PCINIT_MODEMMODULATION_DISABLE_V22BIS 0x00000008L
178#define PCINIT_MODEMMODULATION_DISABLE_V32 0x00000010L
179#define PCINIT_MODEMMODULATION_DISABLE_V32BIS 0x00000020L
180#define PCINIT_MODEMMODULATION_DISABLE_V34 0x00000040L
181#define PCINIT_MODEMMODULATION_DISABLE_V90 0x00000080L
182#define PCINIT_MODEMMODULATION_DISABLE_BELL103 0x00000100L
183#define PCINIT_MODEMMODULATION_DISABLE_BELL212A 0x00000200L
184#define PCINIT_MODEMMODULATION_DISABLE_VFC 0x00000400L
185#define PCINIT_MODEMMODULATION_DISABLE_K56FLEX 0x00000800L
186#define PCINIT_MODEMMODULATION_DISABLE_X2 0x00001000L
187#define PCINIT_MODEMMODULATION_ENABLE_V29FDX 0x00010000L
188#define PCINIT_MODEMMODULATION_ENABLE_V33 0x00020000L
189#define PCINIT_MODEMMODULATION_ENABLE_V90A 0x00040000L
190#define PCINIT_MODEM_TRANSMIT_LEVEL_CHOICES 0x10
191#define PCINIT_MODEM_SPEAKER_OFF 0x00
192#define PCINIT_MODEM_SPEAKER_DURING_TRAIN 0x01
193#define PCINIT_MODEM_SPEAKER_TIL_CONNECT 0x02
194#define PCINIT_MODEM_SPEAKER_ALWAYS_ON 0x03
195#define PCINIT_MODEM_SPEAKER_CHOICES 0x04
196#define PCINIT_MODEM_SPEAKER_VOLUME_MIN 0x00
197#define PCINIT_MODEM_SPEAKER_VOLUME_LOW 0x01
198#define PCINIT_MODEM_SPEAKER_VOLUME_HIGH 0x02
199#define PCINIT_MODEM_SPEAKER_VOLUME_MAX 0x03
200#define PCINIT_MODEM_SPEAKER_VOLUME_CHOICES 0x04
201/*------------------------------------------------------------------*/
202#define PCINIT_FAXCONFIG_DISABLE_FINE 0x0001
203#define PCINIT_FAXCONFIG_DISABLE_ECM 0x0002
204#define PCINIT_FAXCONFIG_ECM_64_BYTES 0x0004
205#define PCINIT_FAXCONFIG_DISABLE_2D_CODING 0x0008
206#define PCINIT_FAXCONFIG_DISABLE_T6_CODING 0x0010
207#define PCINIT_FAXCONFIG_DISABLE_UNCOMPR 0x0020
208#define PCINIT_FAXCONFIG_REFUSE_POLLING 0x0040
209#define PCINIT_FAXCONFIG_HIDE_TOTAL_PAGES 0x0080
210#define PCINIT_FAXCONFIG_HIDE_ALL_HEADLINE 0x0100
211#define PCINIT_FAXCONFIG_HIDE_PAGE_INFO 0x0180
212#define PCINIT_FAXCONFIG_HEADLINE_OPTIONS_MASK 0x0180
213#define PCINIT_FAXCONFIG_DISABLE_FEATURE_FALLBACK 0x0200
214#define PCINIT_FAXCONFIG_V34FAX_CONTROL_RATE_1200 0x0800
215#define PCINIT_FAXCONFIG_DISABLE_V34FAX 0x1000
216#define PCINIT_FAXCONFIG_DISABLE_R8_0770_OR_200 0x01
217#define PCINIT_FAXCONFIG_DISABLE_R8_1540 0x02
218#define PCINIT_FAXCONFIG_DISABLE_R16_1540_OR_400 0x04
219#define PCINIT_FAXCONFIG_DISABLE_R4_0385_OR_100 0x08
220#define PCINIT_FAXCONFIG_DISABLE_300_300 0x10
221#define PCINIT_FAXCONFIG_DISABLE_INCH_BASED 0x40
222#define PCINIT_FAXCONFIG_DISABLE_METRIC_BASED 0x80
223#define PCINIT_FAXCONFIG_REC_WIDTH_ISO_A3 0
224#define PCINIT_FAXCONFIG_REC_WIDTH_ISO_B4 1
225#define PCINIT_FAXCONFIG_REC_WIDTH_ISO_A4 2
226#define PCINIT_FAXCONFIG_REC_WIDTH_COUNT 3
227#define PCINIT_FAXCONFIG_REC_LENGTH_UNLIMITED 0
228#define PCINIT_FAXCONFIG_REC_LENGTH_ISO_B4 1
229#define PCINIT_FAXCONFIG_REC_LENGTH_ISO_A4 2
230#define PCINIT_FAXCONFIG_REC_LENGTH_COUNT 3
231#define PCINIT_FAXCONFIG_SCANLINE_TIME_00_00_00 0
232#define PCINIT_FAXCONFIG_SCANLINE_TIME_05_05_05 1
233#define PCINIT_FAXCONFIG_SCANLINE_TIME_10_05_05 2
234#define PCINIT_FAXCONFIG_SCANLINE_TIME_10_10_10 3
235#define PCINIT_FAXCONFIG_SCANLINE_TIME_20_10_10 4
236#define PCINIT_FAXCONFIG_SCANLINE_TIME_20_20_20 5
237#define PCINIT_FAXCONFIG_SCANLINE_TIME_40_20_20 6
238#define PCINIT_FAXCONFIG_SCANLINE_TIME_40_40_40 7
239#define PCINIT_FAXCONFIG_SCANLINE_TIME_RES_8 8
240#define PCINIT_FAXCONFIG_SCANLINE_TIME_RES_9 9
241#define PCINIT_FAXCONFIG_SCANLINE_TIME_RES_10 10
242#define PCINIT_FAXCONFIG_SCANLINE_TIME_10_10_05 11
243#define PCINIT_FAXCONFIG_SCANLINE_TIME_20_10_05 12
244#define PCINIT_FAXCONFIG_SCANLINE_TIME_20_20_10 13
245#define PCINIT_FAXCONFIG_SCANLINE_TIME_40_20_10 14
246#define PCINIT_FAXCONFIG_SCANLINE_TIME_40_40_20 15
247#define PCINIT_FAXCONFIG_SCANLINE_TIME_COUNT 16
248#define PCINIT_FAXCONFIG_DISABLE_TX_REDUCTION 0x00010000L
249#define PCINIT_FAXCONFIG_DISABLE_PRECODING 0x00020000L
250#define PCINIT_FAXCONFIG_DISABLE_PREEMPHASIS 0x00040000L
251#define PCINIT_FAXCONFIG_DISABLE_SHAPING 0x00080000L
252#define PCINIT_FAXCONFIG_DISABLE_NONLINEAR_EN 0x00100000L
253#define PCINIT_FAXCONFIG_DISABLE_MANUALREDUCT 0x00200000L
254#define PCINIT_FAXCONFIG_DISABLE_16_POINT_TRN 0x00400000L
255#define PCINIT_FAXCONFIG_DISABLE_2400_SYMBOLS 0x01000000L
256#define PCINIT_FAXCONFIG_DISABLE_2743_SYMBOLS 0x02000000L
257#define PCINIT_FAXCONFIG_DISABLE_2800_SYMBOLS 0x04000000L
258#define PCINIT_FAXCONFIG_DISABLE_3000_SYMBOLS 0x08000000L
259#define PCINIT_FAXCONFIG_DISABLE_3200_SYMBOLS 0x10000000L
260#define PCINIT_FAXCONFIG_DISABLE_3429_SYMBOLS 0x20000000L
261/*--------------------------------------------------------------------------*/
262#define PCINIT_XDI_CMA_FOR_ALL_NL_PRIMITIVES 0x01
263/*--------------------------------------------------------------------------*/
264#define PCINIT_FPGA_PLX_ACCESS_SUPPORTED 0x01
265/*--------------------------------------------------------------------------*/
266#endif
267/*--------------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/pc_maint.h b/drivers/isdn/hardware/eicon/pc_maint.h
deleted file mode 100644
index 496f018fb5a2..000000000000
--- a/drivers/isdn/hardware/eicon/pc_maint.h
+++ /dev/null
@@ -1,160 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifdef PLATFORM_GT_32BIT
27/* #define POINTER_32BIT byte * __ptr32 */
28#define POINTER_32BIT dword
29#else
30#define POINTER_32BIT byte *
31#endif
32#if !defined(MIPS_SCOM)
33#define BUFFER_SZ 48
34#define MAINT_OFFS 0x380
35#else
36#define BUFFER_SZ 128
37#if defined(PRI)
38#define MAINT_OFFS 0xef00
39#else
40#define MAINT_OFFS 0xff00
41#endif
42#endif
43#define MIPS_BUFFER_SZ 128
44#if defined(PRI)
45#define MIPS_MAINT_OFFS 0xef00
46#else
47#define MIPS_MAINT_OFFS 0xff00
48#endif
49#define LOG 1
50#define MEMR 2
51#define MEMW 3
52#define IOR 4
53#define IOW 5
54#define B1TEST 6
55#define B2TEST 7
56#define BTESTOFF 8
57#define DSIG_STATS 9
58#define B_CH_STATS 10
59#define D_CH_STATS 11
60#define BL1_STATS 12
61#define BL1_STATS_C 13
62#define GET_VERSION 14
63#define OS_STATS 15
64#define XLOG_SET_MASK 16
65#define XLOG_GET_MASK 17
66#define DSP_READ 20
67#define DSP_WRITE 21
68#define OK 0xff
69#define MORE_EVENTS 0xfe
70#define NO_EVENT 1
71struct DSigStruc
72{
73 byte Id;
74 byte u;
75 byte listen;
76 byte active;
77 byte sin[3];
78 byte bc[6];
79 byte llc[6];
80 byte hlc[6];
81 byte oad[20];
82};
83struct BL1Struc {
84 dword cx_b1;
85 dword cx_b2;
86 dword cr_b1;
87 dword cr_b2;
88 dword px_b1;
89 dword px_b2;
90 dword pr_b1;
91 dword pr_b2;
92 word er_b1;
93 word er_b2;
94};
95struct L2Struc {
96 dword XTotal;
97 dword RTotal;
98 word XError;
99 word RError;
100};
101struct OSStruc {
102 dword free_n;
103};
104typedef union
105{
106 struct DSigStruc DSigStats;
107 struct BL1Struc BL1Stats;
108 struct L2Struc L2Stats;
109 struct OSStruc OSStats;
110 byte b[BUFFER_SZ];
111 word w[BUFFER_SZ >> 1];
112 word l[BUFFER_SZ >> 2]; /* word is wrong, do not use! Use 'd' instead. */
113 dword d[BUFFER_SZ >> 2];
114} BUFFER;
115typedef union
116{
117 struct DSigStruc DSigStats;
118 struct BL1Struc BL1Stats;
119 struct L2Struc L2Stats;
120 struct OSStruc OSStats;
121 byte b[MIPS_BUFFER_SZ];
122 word w[MIPS_BUFFER_SZ >> 1];
123 word l[BUFFER_SZ >> 2]; /* word is wrong, do not use! Use 'd' instead. */
124 dword d[MIPS_BUFFER_SZ >> 2];
125} MIPS_BUFFER;
126#if !defined(MIPS_SCOM)
127struct pc_maint
128{
129 byte req;
130 byte rc;
131 POINTER_32BIT mem;
132 short length;
133 word port;
134 byte fill[6];
135 BUFFER data;
136};
137#else
138struct pc_maint
139{
140 byte req;
141 byte rc;
142 byte reserved[2]; /* R3000 alignment ... */
143 POINTER_32BIT mem;
144 short length;
145 word port;
146 byte fill[4]; /* data at offset 16 */
147 BUFFER data;
148};
149#endif
150struct mi_pc_maint
151{
152 byte req;
153 byte rc;
154 byte reserved[2]; /* R3000 alignment ... */
155 POINTER_32BIT mem;
156 short length;
157 word port;
158 byte fill[4]; /* data at offset 16 */
159 MIPS_BUFFER data;
160};
diff --git a/drivers/isdn/hardware/eicon/pkmaint.h b/drivers/isdn/hardware/eicon/pkmaint.h
deleted file mode 100644
index cf3fb14a8e6f..000000000000
--- a/drivers/isdn/hardware/eicon/pkmaint.h
+++ /dev/null
@@ -1,43 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_XDI_OS_DEPENDENT_PACK_MAIN_ON_BYTE_INC__
27#define __DIVA_XDI_OS_DEPENDENT_PACK_MAIN_ON_BYTE_INC__
28
29
30/*
31 Only one purpose of this compiler dependent file to pack
32 structures, described in pc_maint.h so that no padding
33 will be included.
34
35 With microsoft compile it is done by "pshpack1.h" and
36 after is restored by "poppack.h"
37*/
38
39
40#include "pc_maint.h"
41
42
43#endif
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
deleted file mode 100644
index 62e2073c3690..000000000000
--- a/drivers/isdn/hardware/eicon/platform.h
+++ /dev/null
@@ -1,369 +0,0 @@
1/* $Id: platform.h,v 1.37.4.6 2005/01/31 12:22:20 armin Exp $
2 *
3 * platform.h
4 *
5 *
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000 Eicon Networks
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13
14#ifndef __PLATFORM_H__
15#define __PLATFORM_H__
16
17#if !defined(DIVA_BUILD)
18#define DIVA_BUILD "local"
19#endif
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/skbuff.h>
26#include <linux/vmalloc.h>
27#include <linux/proc_fs.h>
28#include <linux/interrupt.h>
29#include <linux/delay.h>
30#include <linux/list.h>
31#include <asm/types.h>
32#include <asm/io.h>
33
34#include "cardtype.h"
35
36/* activate debuglib for modules only */
37#ifndef MODULE
38#define DIVA_NO_DEBUGLIB
39#endif
40
41#define DIVA_USER_MODE_CARD_CONFIG 1
42#define USE_EXTENDED_DEBUGS 1
43
44#define MAX_ADAPTER 32
45
46#define DIVA_ISTREAM 1
47
48#define MEMORY_SPACE_TYPE 0
49#define PORT_SPACE_TYPE 1
50
51
52#include <linux/string.h>
53
54#ifndef byte
55#define byte u8
56#endif
57
58#ifndef word
59#define word u16
60#endif
61
62#ifndef dword
63#define dword u32
64#endif
65
66#ifndef qword
67#define qword u64
68#endif
69
70#ifndef NULL
71#define NULL ((void *) 0)
72#endif
73
74#ifndef far
75#define far
76#endif
77
78#ifndef _pascal
79#define _pascal
80#endif
81
82#ifndef _loadds
83#define _loadds
84#endif
85
86#ifndef _cdecl
87#define _cdecl
88#endif
89
90#define MEM_TYPE_RAM 0
91#define MEM_TYPE_PORT 1
92#define MEM_TYPE_PROM 2
93#define MEM_TYPE_CTLREG 3
94#define MEM_TYPE_RESET 4
95#define MEM_TYPE_CFG 5
96#define MEM_TYPE_ADDRESS 6
97#define MEM_TYPE_CONFIG 7
98#define MEM_TYPE_CONTROL 8
99
100#define MAX_MEM_TYPE 10
101
102#define DIVA_OS_MEM_ATTACH_RAM(a) ((a)->ram)
103#define DIVA_OS_MEM_ATTACH_PORT(a) ((a)->port)
104#define DIVA_OS_MEM_ATTACH_PROM(a) ((a)->prom)
105#define DIVA_OS_MEM_ATTACH_CTLREG(a) ((a)->ctlReg)
106#define DIVA_OS_MEM_ATTACH_RESET(a) ((a)->reset)
107#define DIVA_OS_MEM_ATTACH_CFG(a) ((a)->cfg)
108#define DIVA_OS_MEM_ATTACH_ADDRESS(a) ((a)->Address)
109#define DIVA_OS_MEM_ATTACH_CONFIG(a) ((a)->Config)
110#define DIVA_OS_MEM_ATTACH_CONTROL(a) ((a)->Control)
111
112#define DIVA_OS_MEM_DETACH_RAM(a, x) do { } while (0)
113#define DIVA_OS_MEM_DETACH_PORT(a, x) do { } while (0)
114#define DIVA_OS_MEM_DETACH_PROM(a, x) do { } while (0)
115#define DIVA_OS_MEM_DETACH_CTLREG(a, x) do { } while (0)
116#define DIVA_OS_MEM_DETACH_RESET(a, x) do { } while (0)
117#define DIVA_OS_MEM_DETACH_CFG(a, x) do { } while (0)
118#define DIVA_OS_MEM_DETACH_ADDRESS(a, x) do { } while (0)
119#define DIVA_OS_MEM_DETACH_CONFIG(a, x) do { } while (0)
120#define DIVA_OS_MEM_DETACH_CONTROL(a, x) do { } while (0)
121
122#define DIVA_INVALID_FILE_HANDLE ((dword)(-1))
123
124#define DIVAS_CONTAINING_RECORD(address, type, field) \
125 ((type *)((char *)(address) - (char *)(&((type *)0)->field)))
126
127extern int sprintf(char *, const char *, ...);
128
129typedef void *LIST_ENTRY;
130
131typedef char DEVICE_NAME[64];
132typedef struct _ISDN_ADAPTER ISDN_ADAPTER;
133typedef struct _ISDN_ADAPTER *PISDN_ADAPTER;
134
135typedef void (*DIVA_DI_PRINTF)(unsigned char *, ...);
136#include "debuglib.h"
137
138#define dtrc(p) DBG_PRV0(p)
139#define dbug(a, p) DBG_PRV1(p)
140
141
142typedef struct e_info_s E_INFO;
143
144typedef char diva_os_dependent_devica_name_t[64];
145typedef void *PDEVICE_OBJECT;
146
147struct _diva_os_soft_isr;
148struct _diva_os_timer;
149struct _ISDN_ADAPTER;
150
151void diva_log_info(unsigned char *, ...);
152
153/*
154** XDI DIDD Interface
155*/
156void diva_xdi_didd_register_adapter(int card);
157void diva_xdi_didd_remove_adapter(int card);
158
159/*
160** memory allocation
161*/
162static __inline__ void *diva_os_malloc(unsigned long flags, unsigned long size)
163{
164 void *ret = NULL;
165
166 if (size) {
167 ret = (void *) vmalloc((unsigned int) size);
168 }
169 return (ret);
170}
171static __inline__ void diva_os_free(unsigned long flags, void *ptr)
172{
173 vfree(ptr);
174}
175
176/*
177** use skbuffs for message buffer
178*/
179typedef struct sk_buff diva_os_message_buffer_s;
180diva_os_message_buffer_s *diva_os_alloc_message_buffer(unsigned long size, void **data_buf);
181void diva_os_free_message_buffer(diva_os_message_buffer_s *dmb);
182#define DIVA_MESSAGE_BUFFER_LEN(x) x->len
183#define DIVA_MESSAGE_BUFFER_DATA(x) x->data
184
185/*
186** mSeconds waiting
187*/
188static __inline__ void diva_os_sleep(dword mSec)
189{
190 msleep(mSec);
191}
192static __inline__ void diva_os_wait(dword mSec)
193{
194 mdelay(mSec);
195}
196
197/*
198** PCI Configuration space access
199*/
200void PCIwrite(byte bus, byte func, int offset, void *data, int length, void *pci_dev_handle);
201void PCIread(byte bus, byte func, int offset, void *data, int length, void *pci_dev_handle);
202
203/*
204** I/O Port utilities
205*/
206int diva_os_register_io_port(void *adapter, int reg, unsigned long port,
207 unsigned long length, const char *name, int id);
208/*
209** I/O port access abstraction
210*/
211byte inpp(void __iomem *);
212word inppw(void __iomem *);
213void inppw_buffer(void __iomem *, void *, int);
214void outppw(void __iomem *, word);
215void outppw_buffer(void __iomem * , void*, int);
216void outpp(void __iomem *, word);
217
218/*
219** IRQ
220*/
221typedef struct _diva_os_adapter_irq_info {
222 byte irq_nr;
223 int registered;
224 char irq_name[24];
225} diva_os_adapter_irq_info_t;
226int diva_os_register_irq(void *context, byte irq, const char *name);
227void diva_os_remove_irq(void *context, byte irq);
228
229#define diva_os_in_irq() in_irq()
230
231/*
232** Spin Lock framework
233*/
234typedef long diva_os_spin_lock_magic_t;
235typedef spinlock_t diva_os_spin_lock_t;
236static __inline__ int diva_os_initialize_spin_lock(spinlock_t *lock, void *unused) { \
237 spin_lock_init(lock); return (0); }
238static __inline__ void diva_os_enter_spin_lock(diva_os_spin_lock_t *a, \
239 diva_os_spin_lock_magic_t *old_irql, \
240 void *dbg) { spin_lock_bh(a); }
241static __inline__ void diva_os_leave_spin_lock(diva_os_spin_lock_t *a, \
242 diva_os_spin_lock_magic_t *old_irql, \
243 void *dbg) { spin_unlock_bh(a); }
244
245#define diva_os_destroy_spin_lock(a, b) do { } while (0)
246
247/*
248** Deffered processing framework
249*/
250typedef int (*diva_os_isr_callback_t)(struct _ISDN_ADAPTER *);
251typedef void (*diva_os_soft_isr_callback_t)(struct _diva_os_soft_isr *psoft_isr, void *context);
252
253typedef struct _diva_os_soft_isr {
254 void *object;
255 diva_os_soft_isr_callback_t callback;
256 void *callback_context;
257 char dpc_thread_name[24];
258} diva_os_soft_isr_t;
259
260int diva_os_initialize_soft_isr(diva_os_soft_isr_t *psoft_isr, diva_os_soft_isr_callback_t callback, void *callback_context);
261int diva_os_schedule_soft_isr(diva_os_soft_isr_t *psoft_isr);
262int diva_os_cancel_soft_isr(diva_os_soft_isr_t *psoft_isr);
263void diva_os_remove_soft_isr(diva_os_soft_isr_t *psoft_isr);
264
265/*
266 Get time service
267*/
268void diva_os_get_time(dword *sec, dword *usec);
269
270/*
271** atomic operation, fake because we use threads
272*/
273typedef int diva_os_atomic_t;
274static inline diva_os_atomic_t
275diva_os_atomic_increment(diva_os_atomic_t *pv)
276{
277 *pv += 1;
278 return (*pv);
279}
280static inline diva_os_atomic_t
281diva_os_atomic_decrement(diva_os_atomic_t *pv)
282{
283 *pv -= 1;
284 return (*pv);
285}
286
287/*
288** CAPI SECTION
289*/
290#define NO_CORNETN
291#define IMPLEMENT_DTMF 1
292#define IMPLEMENT_ECHO_CANCELLER 1
293#define IMPLEMENT_RTP 1
294#define IMPLEMENT_T38 1
295#define IMPLEMENT_FAX_SUB_SEP_PWD 1
296#define IMPLEMENT_V18 1
297#define IMPLEMENT_DTMF_TONE 1
298#define IMPLEMENT_PIAFS 1
299#define IMPLEMENT_FAX_PAPER_FORMATS 1
300#define IMPLEMENT_VOWN 1
301#define IMPLEMENT_CAPIDTMF 1
302#define IMPLEMENT_FAX_NONSTANDARD 1
303#define VSWITCH_SUPPORT 1
304
305#define IMPLEMENT_MARKED_OK_AFTER_FC 1
306
307#define DIVA_IDI_RX_DMA 1
308
309/*
310** endian macros
311**
312** If only... In some cases we did use them for endianness conversion;
313** unfortunately, other uses were real iomem accesses.
314*/
315#define READ_BYTE(addr) readb(addr)
316#define READ_WORD(addr) readw(addr)
317#define READ_DWORD(addr) readl(addr)
318
319#define WRITE_BYTE(addr, v) writeb(v, addr)
320#define WRITE_WORD(addr, v) writew(v, addr)
321#define WRITE_DWORD(addr, v) writel(v, addr)
322
323static inline __u16 GET_WORD(void *addr)
324{
325 return le16_to_cpu(*(__le16 *)addr);
326}
327static inline __u32 GET_DWORD(void *addr)
328{
329 return le32_to_cpu(*(__le32 *)addr);
330}
331static inline void PUT_WORD(void *addr, __u16 v)
332{
333 *(__le16 *)addr = cpu_to_le16(v);
334}
335static inline void PUT_DWORD(void *addr, __u32 v)
336{
337 *(__le32 *)addr = cpu_to_le32(v);
338}
339
340/*
341** 32/64 bit macors
342*/
343#ifdef BITS_PER_LONG
344#if BITS_PER_LONG > 32
345#define PLATFORM_GT_32BIT
346#define ULongToPtr(x) (void *)(unsigned long)(x)
347#endif
348#endif
349
350/*
351** undef os definitions of macros we use
352*/
353#undef ID_MASK
354#undef N_DATA
355#undef ADDR
356
357/*
358** dump file
359*/
360#define diva_os_dump_file_t char
361#define diva_os_board_trace_t char
362#define diva_os_dump_file(__x__) do { } while (0)
363
364/*
365** size of internal arrays
366*/
367#define MAX_DESCRIPTORS 64
368
369#endif /* __PLATFORM_H__ */
diff --git a/drivers/isdn/hardware/eicon/pr_pc.h b/drivers/isdn/hardware/eicon/pr_pc.h
deleted file mode 100644
index a08d6d57a486..000000000000
--- a/drivers/isdn/hardware/eicon/pr_pc.h
+++ /dev/null
@@ -1,76 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26struct pr_ram {
27 word NextReq; /* pointer to next Req Buffer */
28 word NextRc; /* pointer to next Rc Buffer */
29 word NextInd; /* pointer to next Ind Buffer */
30 byte ReqInput; /* number of Req Buffers sent */
31 byte ReqOutput; /* number of Req Buffers returned */
32 byte ReqReserved; /* number of Req Buffers reserved */
33 byte Int; /* ISDN-P interrupt */
34 byte XLock; /* Lock field for arbitration */
35 byte RcOutput; /* number of Rc buffers received */
36 byte IndOutput; /* number of Ind buffers received */
37 byte IMask; /* Interrupt Mask Flag */
38 byte Reserved1[2]; /* reserved field, do not use */
39 byte ReadyInt; /* request field for ready interrupt */
40 byte Reserved2[12]; /* reserved field, do not use */
41 byte InterfaceType; /* interface type 1=16K interface */
42 word Signature; /* ISDN-P initialized indication */
43 byte B[1]; /* buffer space for Req,Ind and Rc */
44};
45typedef struct {
46 word next;
47 byte Req;
48 byte ReqId;
49 byte ReqCh;
50 byte Reserved1;
51 word Reference;
52 byte Reserved[8];
53 PBUFFER XBuffer;
54} REQ;
55typedef struct {
56 word next;
57 byte Rc;
58 byte RcId;
59 byte RcCh;
60 byte Reserved1;
61 word Reference;
62 byte Reserved2[8];
63} RC;
64typedef struct {
65 word next;
66 byte Ind;
67 byte IndId;
68 byte IndCh;
69 byte MInd;
70 word MLength;
71 word Reference;
72 byte RNR;
73 byte Reserved;
74 dword Ack;
75 PBUFFER RBuffer;
76} IND;
diff --git a/drivers/isdn/hardware/eicon/s_4bri.c b/drivers/isdn/hardware/eicon/s_4bri.c
deleted file mode 100644
index ec12165fbf62..000000000000
--- a/drivers/isdn/hardware/eicon/s_4bri.c
+++ /dev/null
@@ -1,510 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include "platform.h"
27#include "di_defs.h"
28#include "pc.h"
29#include "pr_pc.h"
30#include "di.h"
31#include "mi_pc.h"
32#include "pc_maint.h"
33#include "divasync.h"
34#include "pc_init.h"
35#include "io.h"
36#include "helpers.h"
37#include "dsrv4bri.h"
38#include "dsp_defs.h"
39#include "sdp_hdr.h"
40
41/*****************************************************************************/
42#define MAX_XLOG_SIZE (64 * 1024)
43
44/* --------------------------------------------------------------------------
45 Recovery XLOG from QBRI Card
46 -------------------------------------------------------------------------- */
47static void qBri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
48 byte __iomem *base;
49 word *Xlog;
50 dword regs[4], TrapID, offset, size;
51 Xdesc xlogDesc;
52 int factor = (IoAdapter->tasks == 1) ? 1 : 2;
53
54/*
55 * check for trapped MIPS 46xx CPU, dump exception frame
56 */
57
58 base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
59 offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor);
60
61 TrapID = READ_DWORD(&base[0x80]);
62
63 if ((TrapID == 0x99999999) || (TrapID == 0x99999901))
64 {
65 dump_trap_frame(IoAdapter, &base[0x90]);
66 IoAdapter->trapped = 1;
67 }
68
69 regs[0] = READ_DWORD((base + offset) + 0x70);
70 regs[1] = READ_DWORD((base + offset) + 0x74);
71 regs[2] = READ_DWORD((base + offset) + 0x78);
72 regs[3] = READ_DWORD((base + offset) + 0x7c);
73 regs[0] &= IoAdapter->MemorySize - 1;
74
75 if ((regs[0] >= offset)
76 && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1))
77 {
78 if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) {
79 DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
80 return;
81 }
82
83 size = offset + (IoAdapter->MemorySize >> factor) - regs[0];
84 if (size > MAX_XLOG_SIZE)
85 size = MAX_XLOG_SIZE;
86 memcpy_fromio(Xlog, &base[regs[0]], size);
87 xlogDesc.buf = Xlog;
88 xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]);
89 xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]);
90 dump_xlog_buffer(IoAdapter, &xlogDesc);
91 diva_os_free(0, Xlog);
92 IoAdapter->trapped = 2;
93 }
94 DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
95}
96
97/* --------------------------------------------------------------------------
98 Reset QBRI Hardware
99 -------------------------------------------------------------------------- */
100static void reset_qBri_hardware(PISDN_ADAPTER IoAdapter) {
101 word volatile __iomem *qBriReset;
102 byte volatile __iomem *qBriCntrl;
103 byte volatile __iomem *p;
104
105 qBriReset = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
106 WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET);
107 diva_os_wait(1);
108 WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET);
109 diva_os_wait(1);
110 WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_RELOAD_EEPROM);
111 diva_os_wait(1);
112 WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM);
113 diva_os_wait(1);
114 DIVA_OS_MEM_DETACH_PROM(IoAdapter, qBriReset);
115
116 qBriCntrl = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
117 p = &qBriCntrl[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
118 WRITE_DWORD(p, 0);
119 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, qBriCntrl);
120
121 DBG_TRC(("resetted board @ reset addr 0x%08lx", qBriReset))
122 DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p))
123 }
124
125/* --------------------------------------------------------------------------
126 Start Card CPU
127 -------------------------------------------------------------------------- */
128void start_qBri_hardware(PISDN_ADAPTER IoAdapter) {
129 byte volatile __iomem *qBriReset;
130 byte volatile __iomem *p;
131
132 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
133 qBriReset = &p[(DIVA_4BRI_REVISION(IoAdapter)) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
134 WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK);
135 diva_os_wait(2);
136 WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK);
137 diva_os_wait(10);
138 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
139
140 DBG_TRC(("started processor @ addr 0x%08lx", qBriReset))
141 }
142
143/* --------------------------------------------------------------------------
144 Stop Card CPU
145 -------------------------------------------------------------------------- */
146static void stop_qBri_hardware(PISDN_ADAPTER IoAdapter) {
147 byte volatile __iomem *p;
148 dword volatile __iomem *qBriReset;
149 dword volatile __iomem *qBriIrq;
150 dword volatile __iomem *qBriIsacDspReset;
151 int rev2 = DIVA_4BRI_REVISION(IoAdapter);
152 int reset_offset = rev2 ? (MQ2_BREG_RISC) : (MQ_BREG_RISC);
153 int irq_offset = rev2 ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST);
154 int hw_offset = rev2 ? (MQ2_ISAC_DSP_RESET) : (MQ_ISAC_DSP_RESET);
155
156 if (IoAdapter->ControllerNumber > 0)
157 return;
158 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
159 qBriReset = (dword volatile __iomem *)&p[reset_offset];
160 qBriIsacDspReset = (dword volatile __iomem *)&p[hw_offset];
161/*
162 * clear interrupt line (reset Local Interrupt Test Register)
163 */
164 WRITE_DWORD(qBriReset, 0);
165 WRITE_DWORD(qBriIsacDspReset, 0);
166 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
167
168 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
169 WRITE_BYTE(&p[PLX9054_INTCSR], 0x00); /* disable PCI interrupts */
170 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
171
172 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
173 qBriIrq = (dword volatile __iomem *)&p[irq_offset];
174 WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
175 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
176
177 DBG_TRC(("stopped processor @ addr 0x%08lx", qBriReset))
178
179 }
180
181/* --------------------------------------------------------------------------
182 FPGA download
183 -------------------------------------------------------------------------- */
184#define FPGA_NAME_OFFSET 0x10
185
186static byte *qBri_check_FPGAsrc(PISDN_ADAPTER IoAdapter, char *FileName,
187 dword *Length, dword *code) {
188 byte *File;
189 char *fpgaFile, *fpgaType, *fpgaDate, *fpgaTime;
190 dword fpgaFlen, fpgaTlen, fpgaDlen, cnt, year, i;
191
192 if (!(File = (byte *)xdiLoadFile(FileName, Length, 0))) {
193 return (NULL);
194 }
195/*
196 * scan file until FF and put id string into buffer
197 */
198 for (i = 0; File[i] != 0xff;)
199 {
200 if (++i >= *Length)
201 {
202 DBG_FTL(("FPGA download: start of data header not found"))
203 xdiFreeFile(File);
204 return (NULL);
205 }
206 }
207 *code = i++;
208
209 if ((File[i] & 0xF0) != 0x20)
210 {
211 DBG_FTL(("FPGA download: data header corrupted"))
212 xdiFreeFile(File);
213 return (NULL);
214 }
215 fpgaFlen = (dword)File[FPGA_NAME_OFFSET - 1];
216 if (fpgaFlen == 0)
217 fpgaFlen = 12;
218 fpgaFile = (char *)&File[FPGA_NAME_OFFSET];
219 fpgaTlen = (dword)fpgaFile[fpgaFlen + 2];
220 if (fpgaTlen == 0)
221 fpgaTlen = 10;
222 fpgaType = (char *)&fpgaFile[fpgaFlen + 3];
223 fpgaDlen = (dword) fpgaType[fpgaTlen + 2];
224 if (fpgaDlen == 0)
225 fpgaDlen = 11;
226 fpgaDate = (char *)&fpgaType[fpgaTlen + 3];
227 fpgaTime = (char *)&fpgaDate[fpgaDlen + 3];
228 cnt = (dword)(((File[i] & 0x0F) << 20) + (File[i + 1] << 12)
229 + (File[i + 2] << 4) + (File[i + 3] >> 4));
230
231 if ((dword)(i + (cnt / 8)) > *Length)
232 {
233 DBG_FTL(("FPGA download: '%s' file too small (%ld < %ld)",
234 FileName, *Length, code + ((cnt + 7) / 8)))
235 xdiFreeFile(File);
236 return (NULL);
237 }
238 i = 0;
239 do
240 {
241 while ((fpgaDate[i] != '\0')
242 && ((fpgaDate[i] < '0') || (fpgaDate[i] > '9')))
243 {
244 i++;
245 }
246 year = 0;
247 while ((fpgaDate[i] >= '0') && (fpgaDate[i] <= '9'))
248 year = year * 10 + (fpgaDate[i++] - '0');
249 } while ((year < 2000) && (fpgaDate[i] != '\0'));
250
251 switch (IoAdapter->cardType) {
252 case CARDTYPE_DIVASRV_B_2F_PCI:
253 break;
254
255 default:
256 if (year >= 2001) {
257 IoAdapter->fpga_features |= PCINIT_FPGA_PLX_ACCESS_SUPPORTED;
258 }
259 }
260
261 DBG_LOG(("FPGA[%s] file %s (%s %s) len %d",
262 fpgaType, fpgaFile, fpgaDate, fpgaTime, cnt))
263 return (File);
264}
265
266/******************************************************************************/
267
268#define FPGA_PROG 0x0001 /* PROG enable low */
269#define FPGA_BUSY 0x0002 /* BUSY high, DONE low */
270#define FPGA_CS 0x000C /* Enable I/O pins */
271#define FPGA_CCLK 0x0100
272#define FPGA_DOUT 0x0400
273#define FPGA_DIN FPGA_DOUT /* bidirectional I/O */
274
275int qBri_FPGA_download(PISDN_ADAPTER IoAdapter) {
276 int bit;
277 byte *File;
278 dword code, FileLength;
279 word volatile __iomem *addr = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
280 word val, baseval = FPGA_CS | FPGA_PROG;
281
282
283
284 if (DIVA_4BRI_REVISION(IoAdapter))
285 {
286 char *name;
287
288 switch (IoAdapter->cardType) {
289 case CARDTYPE_DIVASRV_B_2F_PCI:
290 name = "dsbri2f.bit";
291 break;
292
293 case CARDTYPE_DIVASRV_B_2M_V2_PCI:
294 case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
295 name = "dsbri2m.bit";
296 break;
297
298 default:
299 name = "ds4bri2.bit";
300 }
301
302 File = qBri_check_FPGAsrc(IoAdapter, name,
303 &FileLength, &code);
304 }
305 else
306 {
307 File = qBri_check_FPGAsrc(IoAdapter, "ds4bri.bit",
308 &FileLength, &code);
309 }
310 if (!File) {
311 DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
312 return (0);
313 }
314/*
315 * prepare download, pulse PROGRAM pin down.
316 */
317 WRITE_WORD(addr, baseval & ~FPGA_PROG); /* PROGRAM low pulse */
318 WRITE_WORD(addr, baseval); /* release */
319 diva_os_wait(50); /* wait until FPGA finished internal memory clear */
320/*
321 * check done pin, must be low
322 */
323 if (READ_WORD(addr) & FPGA_BUSY)
324 {
325 DBG_FTL(("FPGA download: acknowledge for FPGA memory clear missing"))
326 xdiFreeFile(File);
327 DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
328 return (0);
329 }
330/*
331 * put data onto the FPGA
332 */
333 while (code < FileLength)
334 {
335 val = ((word)File[code++]) << 3;
336
337 for (bit = 8; bit-- > 0; val <<= 1) /* put byte onto FPGA */
338 {
339 baseval &= ~FPGA_DOUT; /* clr data bit */
340 baseval |= (val & FPGA_DOUT); /* copy data bit */
341 WRITE_WORD(addr, baseval);
342 WRITE_WORD(addr, baseval | FPGA_CCLK); /* set CCLK hi */
343 WRITE_WORD(addr, baseval | FPGA_CCLK); /* set CCLK hi */
344 WRITE_WORD(addr, baseval); /* set CCLK lo */
345 }
346 }
347 xdiFreeFile(File);
348 diva_os_wait(100);
349 val = READ_WORD(addr);
350
351 DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
352
353 if (!(val & FPGA_BUSY))
354 {
355 DBG_FTL(("FPGA download: chip remains in busy state (0x%04x)", val))
356 return (0);
357 }
358
359 return (1);
360}
361
362static int load_qBri_hardware(PISDN_ADAPTER IoAdapter) {
363 return (0);
364}
365
366/* --------------------------------------------------------------------------
367 Card ISR
368 -------------------------------------------------------------------------- */
369static int qBri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
370 dword volatile __iomem *qBriIrq;
371
372 PADAPTER_LIST_ENTRY QuadroList = IoAdapter->QuadroList;
373
374 word i;
375 int serviced = 0;
376 byte __iomem *p;
377
378 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
379
380 if (!(READ_BYTE(&p[PLX9054_INTCSR]) & 0x80)) {
381 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
382 return (0);
383 }
384 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
385
386/*
387 * clear interrupt line (reset Local Interrupt Test Register)
388 */
389 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
390 qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
391 WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
392 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
393
394 for (i = 0; i < IoAdapter->tasks; ++i)
395 {
396 IoAdapter = QuadroList->QuadroAdapter[i];
397
398 if (IoAdapter && IoAdapter->Initialized
399 && IoAdapter->tst_irq(&IoAdapter->a))
400 {
401 IoAdapter->IrqCount++;
402 serviced = 1;
403 diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
404 }
405 }
406
407 return (serviced);
408}
409
410/* --------------------------------------------------------------------------
411 Does disable the interrupt on the card
412 -------------------------------------------------------------------------- */
413static void disable_qBri_interrupt(PISDN_ADAPTER IoAdapter) {
414 dword volatile __iomem *qBriIrq;
415 byte __iomem *p;
416
417 if (IoAdapter->ControllerNumber > 0)
418 return;
419/*
420 * clear interrupt line (reset Local Interrupt Test Register)
421 */
422 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
423 WRITE_BYTE(&p[PLX9054_INTCSR], 0x00); /* disable PCI interrupts */
424 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
425
426 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
427 qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
428 WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
429 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
430}
431
432/* --------------------------------------------------------------------------
433 Install Adapter Entry Points
434 -------------------------------------------------------------------------- */
435static void set_common_qBri_functions(PISDN_ADAPTER IoAdapter) {
436 ADAPTER *a;
437
438 a = &IoAdapter->a;
439
440 a->ram_in = mem_in;
441 a->ram_inw = mem_inw;
442 a->ram_in_buffer = mem_in_buffer;
443 a->ram_look_ahead = mem_look_ahead;
444 a->ram_out = mem_out;
445 a->ram_outw = mem_outw;
446 a->ram_out_buffer = mem_out_buffer;
447 a->ram_inc = mem_inc;
448
449 IoAdapter->out = pr_out;
450 IoAdapter->dpc = pr_dpc;
451 IoAdapter->tst_irq = scom_test_int;
452 IoAdapter->clr_irq = scom_clear_int;
453 IoAdapter->pcm = (struct pc_maint *)MIPS_MAINT_OFFS;
454
455 IoAdapter->load = load_qBri_hardware;
456
457 IoAdapter->disIrq = disable_qBri_interrupt;
458 IoAdapter->rstFnc = reset_qBri_hardware;
459 IoAdapter->stop = stop_qBri_hardware;
460 IoAdapter->trapFnc = qBri_cpu_trapped;
461
462 IoAdapter->diva_isr_handler = qBri_ISR;
463
464 IoAdapter->a.io = (void *)IoAdapter;
465}
466
467static void set_qBri_functions(PISDN_ADAPTER IoAdapter) {
468 if (!IoAdapter->tasks) {
469 IoAdapter->tasks = MQ_INSTANCE_COUNT;
470 }
471 IoAdapter->MemorySize = MQ_MEMORY_SIZE;
472 set_common_qBri_functions(IoAdapter);
473 diva_os_set_qBri_functions(IoAdapter);
474}
475
476static void set_qBri2_functions(PISDN_ADAPTER IoAdapter) {
477 if (!IoAdapter->tasks) {
478 IoAdapter->tasks = MQ_INSTANCE_COUNT;
479 }
480 IoAdapter->MemorySize = (IoAdapter->tasks == 1) ? BRI2_MEMORY_SIZE : MQ2_MEMORY_SIZE;
481 set_common_qBri_functions(IoAdapter);
482 diva_os_set_qBri2_functions(IoAdapter);
483}
484
485/******************************************************************************/
486
487void prepare_qBri_functions(PISDN_ADAPTER IoAdapter) {
488
489 set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[0]);
490 set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[1]);
491 set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[2]);
492 set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[3]);
493
494}
495
496void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter) {
497 if (!IoAdapter->tasks) {
498 IoAdapter->tasks = MQ_INSTANCE_COUNT;
499 }
500
501 set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[0]);
502 if (IoAdapter->tasks > 1) {
503 set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[1]);
504 set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[2]);
505 set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[3]);
506 }
507
508}
509
510/* -------------------------------------------------------------------------- */
diff --git a/drivers/isdn/hardware/eicon/s_bri.c b/drivers/isdn/hardware/eicon/s_bri.c
deleted file mode 100644
index 6a5bb7462339..000000000000
--- a/drivers/isdn/hardware/eicon/s_bri.c
+++ /dev/null
@@ -1,191 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include "platform.h"
27#include "di_defs.h"
28#include "pc.h"
29#include "pr_pc.h"
30#include "di.h"
31#include "mi_pc.h"
32#include "pc_maint.h"
33#include "divasync.h"
34#include "io.h"
35#include "helpers.h"
36#include "dsrv_bri.h"
37#include "dsp_defs.h"
38/*****************************************************************************/
39#define MAX_XLOG_SIZE (64 * 1024)
40/* --------------------------------------------------------------------------
41 Investigate card state, recovery trace buffer
42 -------------------------------------------------------------------------- */
43static void bri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
44 byte __iomem *addrHi, *addrLo, *ioaddr;
45 word *Xlog;
46 dword regs[4], i, size;
47 Xdesc xlogDesc;
48 byte __iomem *Port;
49/*
50 * first read pointers and trap frame
51 */
52 if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE)))
53 return;
54 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
55 addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
56 addrLo = Port + ADDR;
57 ioaddr = Port + DATA;
58 outpp(addrHi, 0);
59 outppw(addrLo, 0);
60 for (i = 0; i < 0x100; Xlog[i++] = inppw(ioaddr));
61/*
62 * check for trapped MIPS 3xxx CPU, dump only exception frame
63 */
64 if (GET_DWORD(&Xlog[0x80 / sizeof(Xlog[0])]) == 0x99999999)
65 {
66 dump_trap_frame(IoAdapter, &((byte *)Xlog)[0x90]);
67 IoAdapter->trapped = 1;
68 }
69 regs[0] = GET_DWORD(&((byte *)Xlog)[0x70]);
70 regs[1] = GET_DWORD(&((byte *)Xlog)[0x74]);
71 regs[2] = GET_DWORD(&((byte *)Xlog)[0x78]);
72 regs[3] = GET_DWORD(&((byte *)Xlog)[0x7c]);
73 outpp(addrHi, (regs[1] >> 16) & 0x7F);
74 outppw(addrLo, regs[1] & 0xFFFF);
75 xlogDesc.cnt = inppw(ioaddr);
76 outpp(addrHi, (regs[2] >> 16) & 0x7F);
77 outppw(addrLo, regs[2] & 0xFFFF);
78 xlogDesc.out = inppw(ioaddr);
79 xlogDesc.buf = Xlog;
80 regs[0] &= IoAdapter->MemorySize - 1;
81 if ((regs[0] < IoAdapter->MemorySize - 1))
82 {
83 size = IoAdapter->MemorySize - regs[0];
84 if (size > MAX_XLOG_SIZE)
85 size = MAX_XLOG_SIZE;
86 for (i = 0; i < (size / sizeof(*Xlog)); regs[0] += 2)
87 {
88 outpp(addrHi, (regs[0] >> 16) & 0x7F);
89 outppw(addrLo, regs[0] & 0xFFFF);
90 Xlog[i++] = inppw(ioaddr);
91 }
92 dump_xlog_buffer(IoAdapter, &xlogDesc);
93 diva_os_free(0, Xlog);
94 IoAdapter->trapped = 2;
95 }
96 outpp(addrHi, (byte)((BRI_UNCACHED_ADDR(IoAdapter->MemoryBase + IoAdapter->MemorySize -
97 BRI_SHARED_RAM_SIZE)) >> 16));
98 outppw(addrLo, 0x00);
99 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
100}
101/* ---------------------------------------------------------------------
102 Reset hardware
103 --------------------------------------------------------------------- */
104static void reset_bri_hardware(PISDN_ADAPTER IoAdapter) {
105 byte __iomem *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
106 outpp(p, 0x00);
107 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
108}
109/* ---------------------------------------------------------------------
110 Halt system
111 --------------------------------------------------------------------- */
112static void stop_bri_hardware(PISDN_ADAPTER IoAdapter) {
113 byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
114 if (p) {
115 outpp(p, 0x00); /* disable interrupts ! */
116 }
117 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
118 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
119 outpp(p, 0x00); /* clear int, halt cpu */
120 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
121}
122static int load_bri_hardware(PISDN_ADAPTER IoAdapter) {
123 return (0);
124}
125/******************************************************************************/
126static int bri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
127 byte __iomem *p;
128
129 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
130 if (!(inpp(p) & 0x01)) {
131 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
132 return (0);
133 }
134 /*
135 clear interrupt line
136 */
137 outpp(p, 0x08);
138 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
139 IoAdapter->IrqCount++;
140 if (IoAdapter->Initialized) {
141 diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
142 }
143 return (1);
144}
145/* --------------------------------------------------------------------------
146 Disable IRQ in the card hardware
147 -------------------------------------------------------------------------- */
148static void disable_bri_interrupt(PISDN_ADAPTER IoAdapter) {
149 byte __iomem *p;
150 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
151 if (p)
152 {
153 outpp(p, 0x00); /* disable interrupts ! */
154 }
155 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
156 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
157 outpp(p, 0x00); /* clear int, halt cpu */
158 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
159}
160/* -------------------------------------------------------------------------
161 Fill card entry points
162 ------------------------------------------------------------------------- */
163void prepare_maestra_functions(PISDN_ADAPTER IoAdapter) {
164 ADAPTER *a = &IoAdapter->a;
165 a->ram_in = io_in;
166 a->ram_inw = io_inw;
167 a->ram_in_buffer = io_in_buffer;
168 a->ram_look_ahead = io_look_ahead;
169 a->ram_out = io_out;
170 a->ram_outw = io_outw;
171 a->ram_out_buffer = io_out_buffer;
172 a->ram_inc = io_inc;
173 IoAdapter->MemoryBase = BRI_MEMORY_BASE;
174 IoAdapter->MemorySize = BRI_MEMORY_SIZE;
175 IoAdapter->out = pr_out;
176 IoAdapter->dpc = pr_dpc;
177 IoAdapter->tst_irq = scom_test_int;
178 IoAdapter->clr_irq = scom_clear_int;
179 IoAdapter->pcm = (struct pc_maint *)MIPS_MAINT_OFFS;
180 IoAdapter->load = load_bri_hardware;
181 IoAdapter->disIrq = disable_bri_interrupt;
182 IoAdapter->rstFnc = reset_bri_hardware;
183 IoAdapter->stop = stop_bri_hardware;
184 IoAdapter->trapFnc = bri_cpu_trapped;
185 IoAdapter->diva_isr_handler = bri_ISR;
186 /*
187 Prepare OS dependent functions
188 */
189 diva_os_prepare_maestra_functions(IoAdapter);
190}
191/* -------------------------------------------------------------------------- */
diff --git a/drivers/isdn/hardware/eicon/s_pri.c b/drivers/isdn/hardware/eicon/s_pri.c
deleted file mode 100644
index ddd0e0ef8ed7..000000000000
--- a/drivers/isdn/hardware/eicon/s_pri.c
+++ /dev/null
@@ -1,205 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include "platform.h"
27#include "di_defs.h"
28#include "pc.h"
29#include "pr_pc.h"
30#include "di.h"
31#include "mi_pc.h"
32#include "pc_maint.h"
33#include "divasync.h"
34#include "io.h"
35#include "helpers.h"
36#include "dsrv_pri.h"
37#include "dsp_defs.h"
38/*****************************************************************************/
39#define MAX_XLOG_SIZE (64 * 1024)
40/* -------------------------------------------------------------------------
41 Does return offset between ADAPTER->ram and real begin of memory
42 ------------------------------------------------------------------------- */
43static dword pri_ram_offset(ADAPTER *a) {
44 return ((dword)MP_SHARED_RAM_OFFSET);
45}
46/* -------------------------------------------------------------------------
47 Recovery XLOG buffer from the card
48 ------------------------------------------------------------------------- */
49static void pri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
50 byte __iomem *base;
51 word *Xlog;
52 dword regs[4], TrapID, size;
53 Xdesc xlogDesc;
54/*
55 * check for trapped MIPS 46xx CPU, dump exception frame
56 */
57 base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
58 TrapID = READ_DWORD(&base[0x80]);
59 if ((TrapID == 0x99999999) || (TrapID == 0x99999901))
60 {
61 dump_trap_frame(IoAdapter, &base[0x90]);
62 IoAdapter->trapped = 1;
63 }
64 regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]);
65 regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]);
66 regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]);
67 regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]);
68 regs[0] &= IoAdapter->MemorySize - 1;
69 if ((regs[0] < IoAdapter->MemorySize - 1))
70 {
71 if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) {
72 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
73 return;
74 }
75 size = IoAdapter->MemorySize - regs[0];
76 if (size > MAX_XLOG_SIZE)
77 size = MAX_XLOG_SIZE;
78 memcpy_fromio(Xlog, &base[regs[0]], size);
79 xlogDesc.buf = Xlog;
80 xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]);
81 xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]);
82 dump_xlog_buffer(IoAdapter, &xlogDesc);
83 diva_os_free(0, Xlog);
84 IoAdapter->trapped = 2;
85 }
86 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
87}
88/* -------------------------------------------------------------------------
89 Hardware reset of PRI card
90 ------------------------------------------------------------------------- */
91static void reset_pri_hardware(PISDN_ADAPTER IoAdapter) {
92 byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
93 WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
94 diva_os_wait(50);
95 WRITE_BYTE(p, 0x00);
96 diva_os_wait(50);
97 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
98}
99/* -------------------------------------------------------------------------
100 Stop Card Hardware
101 ------------------------------------------------------------------------- */
102static void stop_pri_hardware(PISDN_ADAPTER IoAdapter) {
103 dword i;
104 byte __iomem *p;
105 dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
106 WRITE_DWORD(&cfgReg[3], 0);
107 WRITE_DWORD(&cfgReg[1], 0);
108 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
109 IoAdapter->a.ram_out(&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU);
110 i = 0;
111 while ((i < 100) && (IoAdapter->a.ram_in(&IoAdapter->a, &RAM->SWReg) != 0))
112 {
113 diva_os_wait(1);
114 i++;
115 }
116 DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
117 cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
118 WRITE_DWORD(&cfgReg[0], ((dword)(~0x03E00000)));
119 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
120 diva_os_wait(1);
121 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
122 WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
123 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
124}
125static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
126 return (0);
127}
128/* --------------------------------------------------------------------------
129 PRI Adapter interrupt Service Routine
130 -------------------------------------------------------------------------- */
131static int pri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
132 byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
133 if (!(READ_DWORD(cfg) & 0x80000000)) {
134 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
135 return (0);
136 }
137 /*
138 clear interrupt line
139 */
140 WRITE_DWORD(cfg, (dword)~0x03E00000);
141 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
142 IoAdapter->IrqCount++;
143 if (IoAdapter->Initialized)
144 {
145 diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
146 }
147 return (1);
148}
149/* -------------------------------------------------------------------------
150 Disable interrupt in the card hardware
151 ------------------------------------------------------------------------- */
152static void disable_pri_interrupt(PISDN_ADAPTER IoAdapter) {
153 dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
154 WRITE_DWORD(&cfgReg[3], 0);
155 WRITE_DWORD(&cfgReg[1], 0);
156 WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000));
157 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
158}
159/* -------------------------------------------------------------------------
160 Install entry points for PRI Adapter
161 ------------------------------------------------------------------------- */
162static void prepare_common_pri_functions(PISDN_ADAPTER IoAdapter) {
163 ADAPTER *a = &IoAdapter->a;
164 a->ram_in = mem_in;
165 a->ram_inw = mem_inw;
166 a->ram_in_buffer = mem_in_buffer;
167 a->ram_look_ahead = mem_look_ahead;
168 a->ram_out = mem_out;
169 a->ram_outw = mem_outw;
170 a->ram_out_buffer = mem_out_buffer;
171 a->ram_inc = mem_inc;
172 a->ram_offset = pri_ram_offset;
173 a->ram_out_dw = mem_out_dw;
174 a->ram_in_dw = mem_in_dw;
175 a->istream_wakeup = pr_stream;
176 IoAdapter->out = pr_out;
177 IoAdapter->dpc = pr_dpc;
178 IoAdapter->tst_irq = scom_test_int;
179 IoAdapter->clr_irq = scom_clear_int;
180 IoAdapter->pcm = (struct pc_maint *)(MIPS_MAINT_OFFS
181 - MP_SHARED_RAM_OFFSET);
182 IoAdapter->load = load_pri_hardware;
183 IoAdapter->disIrq = disable_pri_interrupt;
184 IoAdapter->rstFnc = reset_pri_hardware;
185 IoAdapter->stop = stop_pri_hardware;
186 IoAdapter->trapFnc = pri_cpu_trapped;
187 IoAdapter->diva_isr_handler = pri_ISR;
188}
189/* -------------------------------------------------------------------------
190 Install entry points for PRI Adapter
191 ------------------------------------------------------------------------- */
192void prepare_pri_functions(PISDN_ADAPTER IoAdapter) {
193 IoAdapter->MemorySize = MP_MEMORY_SIZE;
194 prepare_common_pri_functions(IoAdapter);
195 diva_os_prepare_pri_functions(IoAdapter);
196}
197/* -------------------------------------------------------------------------
198 Install entry points for PRI Rev.2 Adapter
199 ------------------------------------------------------------------------- */
200void prepare_pri2_functions(PISDN_ADAPTER IoAdapter) {
201 IoAdapter->MemorySize = MP2_MEMORY_SIZE;
202 prepare_common_pri_functions(IoAdapter);
203 diva_os_prepare_pri2_functions(IoAdapter);
204}
205/* ------------------------------------------------------------------------- */
diff --git a/drivers/isdn/hardware/eicon/sdp_hdr.h b/drivers/isdn/hardware/eicon/sdp_hdr.h
deleted file mode 100644
index 5e20f8d68673..000000000000
--- a/drivers/isdn/hardware/eicon/sdp_hdr.h
+++ /dev/null
@@ -1,117 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#ifndef __DIVA_SOFT_DSP_TASK_ENTRY_H__
27#define __DIVA_SOFT_DSP_TASK_ENTRY_H__
28/*
29 The soft DSP image is described by binary header contained on begin of this
30 image:
31 OFFSET FROM IMAGE START | VARIABLE
32 ------------------------------------------------------------------------
33 DIVA_MIPS_TASK_IMAGE_LINK_OFFS | link to the next image
34 ----------------------------------------------------------------------
35 DIVA_MIPS_TASK_IMAGE_GP_OFFS | image gp register value, void*
36 ----------------------------------------------------------------------
37 DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS | diva_mips_sdp_task_entry_t*
38 ----------------------------------------------------------------------
39 DIVA_MIPS_TASK_IMAGE_LOAD_ADDR_OFFS | image image start address (void*)
40 ----------------------------------------------------------------------
41 DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS | image image end address (void*)
42 ----------------------------------------------------------------------
43 DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS | image id string char[...];
44 ----------------------------------------------------------------------
45*/
46#define DIVA_MIPS_TASK_IMAGE_LINK_OFFS 0x6C
47#define DIVA_MIPS_TASK_IMAGE_GP_OFFS 0x70
48#define DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS 0x74
49#define DIVA_MIPS_TASK_IMAGE_LOAD_ADDR_OFFS 0x78
50#define DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS 0x7c
51#define DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS 0x80
52/*
53 This function is called in order to set GP register of this task
54 This function should be always called before any function of the
55 task is called
56*/
57typedef void (*diva_task_set_prog_gp_proc_t)(void *new_gp);
58/*
59 This function is called to clear .bss at task initialization step
60*/
61typedef void (*diva_task_sys_reset_proc_t)(void);
62/*
63 This function is called in order to provide GP of master call to
64 task, that will be used by calls from the task to the master
65*/
66typedef void (*diva_task_set_main_gp_proc_t)(void *main_gp);
67/*
68 This function is called to provide address of 'dprintf' function
69 to the task
70*/
71typedef word (*diva_prt_proc_t)(char *, ...);
72typedef void (*diva_task_set_prt_proc_t)(diva_prt_proc_t fn);
73/*
74 This function is called to set task PID
75*/
76typedef void (*diva_task_set_pid_proc_t)(dword id);
77/*
78 This function is called for run-time task init
79*/
80typedef int (*diva_task_run_time_init_proc_t)(void*, dword);
81/*
82 This function is called from system scheduler or from timer
83*/
84typedef void (*diva_task_callback_proc_t)(void);
85/*
86 This callback is used by task to get current time im mS
87*/
88typedef dword (*diva_task_get_tick_count_proc_t)(void);
89typedef void (*diva_task_set_get_time_proc_t)(\
90 diva_task_get_tick_count_proc_t fn);
91typedef struct _diva_mips_sdp_task_entry {
92 diva_task_set_prog_gp_proc_t set_gp_proc;
93 diva_task_sys_reset_proc_t sys_reset_proc;
94 diva_task_set_main_gp_proc_t set_main_gp_proc;
95 diva_task_set_prt_proc_t set_dprintf_proc;
96 diva_task_set_pid_proc_t set_pid_proc;
97 diva_task_run_time_init_proc_t run_time_init_proc;
98 diva_task_callback_proc_t task_callback_proc;
99 diva_task_callback_proc_t timer_callback_proc;
100 diva_task_set_get_time_proc_t set_get_time_proc;
101 void *last_entry_proc;
102} diva_mips_sdp_task_entry_t;
103/*
104 'last_entry_proc' should be set to zero and is used for future extensuios
105*/
106typedef struct _diva_mips_sw_task {
107 diva_mips_sdp_task_entry_t sdp_entry;
108 void *sdp_gp_reg;
109 void *own_gp_reg;
110} diva_mips_sw_task_t;
111#if !defined(DIVA_BRI2F_SDP_1_NAME)
112#define DIVA_BRI2F_SDP_1_NAME "sdp0.2q0"
113#endif
114#if !defined(DIVA_BRI2F_SDP_2_NAME)
115#define DIVA_BRI2F_SDP_2_NAME "sdp1.2q0"
116#endif
117#endif
diff --git a/drivers/isdn/hardware/eicon/um_idi.c b/drivers/isdn/hardware/eicon/um_idi.c
deleted file mode 100644
index db4dd4ff3642..000000000000
--- a/drivers/isdn/hardware/eicon/um_idi.c
+++ /dev/null
@@ -1,886 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/* $Id: um_idi.c,v 1.14 2004/03/21 17:54:37 armin Exp $ */
3
4#include "platform.h"
5#include "di_defs.h"
6#include "pc.h"
7#include "dqueue.h"
8#include "adapter.h"
9#include "entity.h"
10#include "um_xdi.h"
11#include "um_idi.h"
12#include "debuglib.h"
13#include "divasync.h"
14
15#define DIVAS_MAX_XDI_ADAPTERS 64
16
17/* --------------------------------------------------------------------------
18 IMPORTS
19 -------------------------------------------------------------------------- */
20extern void diva_os_wakeup_read(void *os_context);
21extern void diva_os_wakeup_close(void *os_context);
22/* --------------------------------------------------------------------------
23 LOCALS
24 -------------------------------------------------------------------------- */
25static LIST_HEAD(adapter_q);
26static diva_os_spin_lock_t adapter_lock;
27
28static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr);
29static void cleanup_adapter(diva_um_idi_adapter_t *a);
30static void cleanup_entity(divas_um_idi_entity_t *e);
31static int diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t *a,
32 diva_um_idi_adapter_features_t
33 *features);
34static int process_idi_request(divas_um_idi_entity_t *e,
35 const diva_um_idi_req_hdr_t *req);
36static int process_idi_rc(divas_um_idi_entity_t *e, byte rc);
37static int process_idi_ind(divas_um_idi_entity_t *e, byte ind);
38static int write_return_code(divas_um_idi_entity_t *e, byte rc);
39
40/* --------------------------------------------------------------------------
41 MAIN
42 -------------------------------------------------------------------------- */
43int diva_user_mode_idi_init(void)
44{
45 diva_os_initialize_spin_lock(&adapter_lock, "adapter");
46 return (0);
47}
48
49/* --------------------------------------------------------------------------
50 Copy adapter features to user supplied buffer
51 -------------------------------------------------------------------------- */
52static int
53diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t *a,
54 diva_um_idi_adapter_features_t *
55 features)
56{
57 IDI_SYNC_REQ sync_req;
58
59 if ((a) && (a->d.request)) {
60 features->type = a->d.type;
61 features->features = a->d.features;
62 features->channels = a->d.channels;
63 memset(features->name, 0, sizeof(features->name));
64
65 sync_req.GetName.Req = 0;
66 sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME;
67 (*(a->d.request)) ((ENTITY *)&sync_req);
68 strlcpy(features->name, sync_req.GetName.name,
69 sizeof(features->name));
70
71 sync_req.GetSerial.Req = 0;
72 sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
73 sync_req.GetSerial.serial = 0;
74 (*(a->d.request))((ENTITY *)&sync_req);
75 features->serial_number = sync_req.GetSerial.serial;
76 }
77
78 return ((a) ? 0 : -1);
79}
80
81/* --------------------------------------------------------------------------
82 REMOVE ADAPTER
83 -------------------------------------------------------------------------- */
84void diva_user_mode_idi_remove_adapter(int adapter_nr)
85{
86 struct list_head *tmp;
87 diva_um_idi_adapter_t *a;
88
89 list_for_each(tmp, &adapter_q) {
90 a = list_entry(tmp, diva_um_idi_adapter_t, link);
91 if (a->adapter_nr == adapter_nr) {
92 list_del(tmp);
93 cleanup_adapter(a);
94 DBG_LOG(("DIDD: del adapter(%d)", a->adapter_nr));
95 diva_os_free(0, a);
96 break;
97 }
98 }
99}
100
101/* --------------------------------------------------------------------------
102 CALLED ON DRIVER EXIT (UNLOAD)
103 -------------------------------------------------------------------------- */
104void diva_user_mode_idi_finit(void)
105{
106 struct list_head *tmp, *safe;
107 diva_um_idi_adapter_t *a;
108
109 list_for_each_safe(tmp, safe, &adapter_q) {
110 a = list_entry(tmp, diva_um_idi_adapter_t, link);
111 list_del(tmp);
112 cleanup_adapter(a);
113 DBG_LOG(("DIDD: del adapter(%d)", a->adapter_nr));
114 diva_os_free(0, a);
115 }
116 diva_os_destroy_spin_lock(&adapter_lock, "adapter");
117}
118
119/* -------------------------------------------------------------------------
120 CREATE AND INIT IDI ADAPTER
121 ------------------------------------------------------------------------- */
122int diva_user_mode_idi_create_adapter(const DESCRIPTOR *d, int adapter_nr)
123{
124 diva_os_spin_lock_magic_t old_irql;
125 diva_um_idi_adapter_t *a =
126 (diva_um_idi_adapter_t *) diva_os_malloc(0,
127 sizeof
128 (diva_um_idi_adapter_t));
129
130 if (!a) {
131 return (-1);
132 }
133 memset(a, 0x00, sizeof(*a));
134 INIT_LIST_HEAD(&a->entity_q);
135
136 a->d = *d;
137 a->adapter_nr = adapter_nr;
138
139 DBG_LOG(("DIDD_ADD A(%d), type:%02x, features:%04x, channels:%d",
140 adapter_nr, a->d.type, a->d.features, a->d.channels));
141
142 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "create_adapter");
143 list_add_tail(&a->link, &adapter_q);
144 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "create_adapter");
145 return (0);
146}
147
148/* ------------------------------------------------------------------------
149 Find adapter by Adapter number
150 ------------------------------------------------------------------------ */
151static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr)
152{
153 diva_um_idi_adapter_t *a = NULL;
154 struct list_head *tmp;
155
156 list_for_each(tmp, &adapter_q) {
157 a = list_entry(tmp, diva_um_idi_adapter_t, link);
158 DBG_TRC(("find_adapter: (%d)-(%d)", nr, a->adapter_nr));
159 if (a->adapter_nr == (int)nr)
160 break;
161 a = NULL;
162 }
163 return (a);
164}
165
166/* ------------------------------------------------------------------------
167 Cleanup this adapter and cleanup/delete all entities assigned
168 to this adapter
169 ------------------------------------------------------------------------ */
170static void cleanup_adapter(diva_um_idi_adapter_t *a)
171{
172 struct list_head *tmp, *safe;
173 divas_um_idi_entity_t *e;
174
175 list_for_each_safe(tmp, safe, &a->entity_q) {
176 e = list_entry(tmp, divas_um_idi_entity_t, link);
177 list_del(tmp);
178 cleanup_entity(e);
179 if (e->os_context) {
180 diva_os_wakeup_read(e->os_context);
181 diva_os_wakeup_close(e->os_context);
182 }
183 }
184 memset(&a->d, 0x00, sizeof(DESCRIPTOR));
185}
186
187/* ------------------------------------------------------------------------
188 Cleanup, but NOT delete this entity
189 ------------------------------------------------------------------------ */
190static void cleanup_entity(divas_um_idi_entity_t *e)
191{
192 e->os_ref = NULL;
193 e->status = 0;
194 e->adapter = NULL;
195 e->e.Id = 0;
196 e->rc_count = 0;
197
198 e->status |= DIVA_UM_IDI_REMOVED;
199 e->status |= DIVA_UM_IDI_REMOVE_PENDING;
200
201 diva_data_q_finit(&e->data);
202 diva_data_q_finit(&e->rc);
203}
204
205
206/* ------------------------------------------------------------------------
207 Create ENTITY, link it to the adapter and remove pointer to entity
208 ------------------------------------------------------------------------ */
209void *divas_um_idi_create_entity(dword adapter_nr, void *file)
210{
211 divas_um_idi_entity_t *e;
212 diva_um_idi_adapter_t *a;
213 diva_os_spin_lock_magic_t old_irql;
214
215 if ((e = (divas_um_idi_entity_t *) diva_os_malloc(0, sizeof(*e)))) {
216 memset(e, 0x00, sizeof(*e));
217 if (!
218 (e->os_context =
219 diva_os_malloc(0, diva_os_get_context_size()))) {
220 DBG_LOG(("E(%08x) no memory for os context", e));
221 diva_os_free(0, e);
222 return NULL;
223 }
224 memset(e->os_context, 0x00, diva_os_get_context_size());
225
226 if ((diva_data_q_init(&e->data, 2048 + 512, 16))) {
227 diva_os_free(0, e->os_context);
228 diva_os_free(0, e);
229 return NULL;
230 }
231 if ((diva_data_q_init(&e->rc, sizeof(diva_um_idi_ind_hdr_t), 2))) {
232 diva_data_q_finit(&e->data);
233 diva_os_free(0, e->os_context);
234 diva_os_free(0, e);
235 return NULL;
236 }
237
238 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "create_entity");
239 /*
240 Look for Adapter requested
241 */
242 if (!(a = diva_um_idi_find_adapter(adapter_nr))) {
243 /*
244 No adapter was found, or this adapter was removed
245 */
246 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "create_entity");
247
248 DBG_LOG(("A: no adapter(%ld)", adapter_nr));
249
250 cleanup_entity(e);
251 diva_os_free(0, e->os_context);
252 diva_os_free(0, e);
253
254 return NULL;
255 }
256
257 e->os_ref = file; /* link to os handle */
258 e->adapter = a; /* link to adapter */
259
260 list_add_tail(&e->link, &a->entity_q); /* link from adapter */
261
262 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "create_entity");
263
264 DBG_LOG(("A(%ld), create E(%08x)", adapter_nr, e));
265 }
266
267 return (e);
268}
269
270/* ------------------------------------------------------------------------
271 Unlink entity and free memory
272 ------------------------------------------------------------------------ */
273int divas_um_idi_delete_entity(int adapter_nr, void *entity)
274{
275 divas_um_idi_entity_t *e;
276 diva_um_idi_adapter_t *a;
277 diva_os_spin_lock_magic_t old_irql;
278
279 if (!(e = (divas_um_idi_entity_t *) entity))
280 return (-1);
281
282 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "delete_entity");
283 if ((a = e->adapter)) {
284 list_del(&e->link);
285 }
286 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "delete_entity");
287
288 diva_um_idi_stop_wdog(entity);
289 cleanup_entity(e);
290 diva_os_free(0, e->os_context);
291 memset(e, 0x00, sizeof(*e));
292
293 DBG_LOG(("A(%d) remove E:%08x", adapter_nr, e));
294 diva_os_free(0, e);
295
296 return (0);
297}
298
299/* --------------------------------------------------------------------------
300 Called by application to read data from IDI
301 -------------------------------------------------------------------------- */
302int diva_um_idi_read(void *entity,
303 void *os_handle,
304 void *dst,
305 int max_length, divas_um_idi_copy_to_user_fn_t cp_fn)
306{
307 divas_um_idi_entity_t *e;
308 diva_um_idi_adapter_t *a;
309 const void *data;
310 int length, ret = 0;
311 diva_um_idi_data_queue_t *q;
312 diva_os_spin_lock_magic_t old_irql;
313
314 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "read");
315
316 e = (divas_um_idi_entity_t *) entity;
317 if (!e || (!(a = e->adapter)) ||
318 (e->status & DIVA_UM_IDI_REMOVE_PENDING) ||
319 (e->status & DIVA_UM_IDI_REMOVED) ||
320 (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
321 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "read");
322 DBG_ERR(("E(%08x) read failed - adapter removed", e))
323 return (-1);
324 }
325
326 DBG_TRC(("A(%d) E(%08x) read(%d)", a->adapter_nr, e, max_length));
327
328 /*
329 Try to read return code first
330 */
331 data = diva_data_q_get_segment4read(&e->rc);
332 q = &e->rc;
333
334 /*
335 No return codes available, read indications now
336 */
337 if (!data) {
338 if (!(e->status & DIVA_UM_IDI_RC_PENDING)) {
339 DBG_TRC(("A(%d) E(%08x) read data", a->adapter_nr, e));
340 data = diva_data_q_get_segment4read(&e->data);
341 q = &e->data;
342 }
343 } else {
344 e->status &= ~DIVA_UM_IDI_RC_PENDING;
345 DBG_TRC(("A(%d) E(%08x) read rc", a->adapter_nr, e));
346 }
347
348 if (data) {
349 if ((length = diva_data_q_get_segment_length(q)) >
350 max_length) {
351 /*
352 Not enough space to read message
353 */
354 DBG_ERR(("A: A(%d) E(%08x) read small buffer",
355 a->adapter_nr, e, ret));
356 diva_os_leave_spin_lock(&adapter_lock, &old_irql,
357 "read");
358 return (-2);
359 }
360 /*
361 Copy it to user, this function does access ONLY locked an verified
362 memory, also we can access it witch spin lock held
363 */
364
365 if ((ret = (*cp_fn) (os_handle, dst, data, length)) >= 0) {
366 /*
367 Acknowledge only if read was successful
368 */
369 diva_data_q_ack_segment4read(q);
370 }
371 }
372
373
374 DBG_TRC(("A(%d) E(%08x) read=%d", a->adapter_nr, e, ret));
375
376 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "read");
377
378 return (ret);
379}
380
381
382int diva_um_idi_write(void *entity,
383 void *os_handle,
384 const void *src,
385 int length, divas_um_idi_copy_from_user_fn_t cp_fn)
386{
387 divas_um_idi_entity_t *e;
388 diva_um_idi_adapter_t *a;
389 diva_um_idi_req_hdr_t *req;
390 void *data;
391 int ret = 0;
392 diva_os_spin_lock_magic_t old_irql;
393
394 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "write");
395
396 e = (divas_um_idi_entity_t *) entity;
397 if (!e || (!(a = e->adapter)) ||
398 (e->status & DIVA_UM_IDI_REMOVE_PENDING) ||
399 (e->status & DIVA_UM_IDI_REMOVED) ||
400 (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
401 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
402 DBG_ERR(("E(%08x) write failed - adapter removed", e))
403 return (-1);
404 }
405
406 DBG_TRC(("A(%d) E(%08x) write(%d)", a->adapter_nr, e, length));
407
408 if ((length < sizeof(*req)) || (length > sizeof(e->buffer))) {
409 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
410 return (-2);
411 }
412
413 if (e->status & DIVA_UM_IDI_RC_PENDING) {
414 DBG_ERR(("A: A(%d) E(%08x) rc pending", a->adapter_nr, e));
415 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
416 return (-1); /* should wait for RC code first */
417 }
418
419 /*
420 Copy function does access only locked verified memory,
421 also it can be called with spin lock held
422 */
423 if ((ret = (*cp_fn) (os_handle, e->buffer, src, length)) < 0) {
424 DBG_TRC(("A: A(%d) E(%08x) write error=%d", a->adapter_nr,
425 e, ret));
426 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
427 return (ret);
428 }
429
430 req = (diva_um_idi_req_hdr_t *)&e->buffer[0];
431
432 switch (req->type) {
433 case DIVA_UM_IDI_GET_FEATURES:{
434 DBG_LOG(("A(%d) get_features", a->adapter_nr));
435 if (!(data =
436 diva_data_q_get_segment4write(&e->data))) {
437 DBG_ERR(("A(%d) get_features, no free buffer",
438 a->adapter_nr));
439 diva_os_leave_spin_lock(&adapter_lock,
440 &old_irql,
441 "write");
442 return (0);
443 }
444 diva_user_mode_idi_adapter_features(a, &(((diva_um_idi_ind_hdr_t
445 *) data)->hdr.features));
446 ((diva_um_idi_ind_hdr_t *) data)->type =
447 DIVA_UM_IDI_IND_FEATURES;
448 ((diva_um_idi_ind_hdr_t *) data)->data_length = 0;
449 diva_data_q_ack_segment4write(&e->data,
450 sizeof(diva_um_idi_ind_hdr_t));
451
452 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
453
454 diva_os_wakeup_read(e->os_context);
455 }
456 break;
457
458 case DIVA_UM_IDI_REQ:
459 case DIVA_UM_IDI_REQ_MAN:
460 case DIVA_UM_IDI_REQ_SIG:
461 case DIVA_UM_IDI_REQ_NET:
462 DBG_TRC(("A(%d) REQ(%02d)-(%02d)-(%08x)", a->adapter_nr,
463 req->Req, req->ReqCh,
464 req->type & DIVA_UM_IDI_REQ_TYPE_MASK));
465 switch (process_idi_request(e, req)) {
466 case -1:
467 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
468 return (-1);
469 case -2:
470 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
471 diva_os_wakeup_read(e->os_context);
472 break;
473 default:
474 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
475 break;
476 }
477 break;
478
479 default:
480 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
481 return (-1);
482 }
483
484 DBG_TRC(("A(%d) E(%08x) write=%d", a->adapter_nr, e, ret));
485
486 return (ret);
487}
488
489/* --------------------------------------------------------------------------
490 CALLBACK FROM XDI
491 -------------------------------------------------------------------------- */
492static void diva_um_idi_xdi_callback(ENTITY *entity)
493{
494 divas_um_idi_entity_t *e = DIVAS_CONTAINING_RECORD(entity,
495 divas_um_idi_entity_t,
496 e);
497 diva_os_spin_lock_magic_t old_irql;
498 int call_wakeup = 0;
499
500 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "xdi_callback");
501
502 if (e->e.complete == 255) {
503 if (!(e->status & DIVA_UM_IDI_REMOVE_PENDING)) {
504 diva_um_idi_stop_wdog(e);
505 }
506 if ((call_wakeup = process_idi_rc(e, e->e.Rc))) {
507 if (e->rc_count) {
508 e->rc_count--;
509 }
510 }
511 e->e.Rc = 0;
512 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "xdi_callback");
513
514 if (call_wakeup) {
515 diva_os_wakeup_read(e->os_context);
516 diva_os_wakeup_close(e->os_context);
517 }
518 } else {
519 if (e->status & DIVA_UM_IDI_REMOVE_PENDING) {
520 e->e.RNum = 0;
521 e->e.RNR = 2;
522 } else {
523 call_wakeup = process_idi_ind(e, e->e.Ind);
524 }
525 e->e.Ind = 0;
526 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "xdi_callback");
527 if (call_wakeup) {
528 diva_os_wakeup_read(e->os_context);
529 }
530 }
531}
532
533static int process_idi_request(divas_um_idi_entity_t *e,
534 const diva_um_idi_req_hdr_t *req)
535{
536 int assign = 0;
537 byte Req = (byte) req->Req;
538 dword type = req->type & DIVA_UM_IDI_REQ_TYPE_MASK;
539
540 if (!e->e.Id || !e->e.callback) { /* not assigned */
541 if (Req != ASSIGN) {
542 DBG_ERR(("A: A(%d) E(%08x) not assigned",
543 e->adapter->adapter_nr, e));
544 return (-1); /* NOT ASSIGNED */
545 } else {
546 switch (type) {
547 case DIVA_UM_IDI_REQ_TYPE_MAN:
548 e->e.Id = MAN_ID;
549 DBG_TRC(("A(%d) E(%08x) assign MAN",
550 e->adapter->adapter_nr, e));
551 break;
552
553 case DIVA_UM_IDI_REQ_TYPE_SIG:
554 e->e.Id = DSIG_ID;
555 DBG_TRC(("A(%d) E(%08x) assign SIG",
556 e->adapter->adapter_nr, e));
557 break;
558
559 case DIVA_UM_IDI_REQ_TYPE_NET:
560 e->e.Id = NL_ID;
561 DBG_TRC(("A(%d) E(%08x) assign NET",
562 e->adapter->adapter_nr, e));
563 break;
564
565 default:
566 DBG_ERR(("A: A(%d) E(%08x) unknown type=%08x",
567 e->adapter->adapter_nr, e,
568 type));
569 return (-1);
570 }
571 }
572 e->e.XNum = 1;
573 e->e.RNum = 1;
574 e->e.callback = diva_um_idi_xdi_callback;
575 e->e.X = &e->XData;
576 e->e.R = &e->RData;
577 assign = 1;
578 }
579 e->status |= DIVA_UM_IDI_RC_PENDING;
580 e->e.Req = Req;
581 e->e.ReqCh = (byte) req->ReqCh;
582 e->e.X->PLength = (word) req->data_length;
583 e->e.X->P = (byte *)&req[1]; /* Our buffer is safe */
584
585 DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))",
586 e->adapter->adapter_nr, e, e->e.Id, e->e.Req,
587 e->e.ReqCh, e->e.X->PLength));
588
589 e->rc_count++;
590
591 if (e->adapter && e->adapter->d.request) {
592 diva_um_idi_start_wdog(e);
593 (*(e->adapter->d.request)) (&e->e);
594 }
595
596 if (assign) {
597 if (e->e.Rc == OUT_OF_RESOURCES) {
598 /*
599 XDI has no entities more, call was not forwarded to the card,
600 no callback will be scheduled
601 */
602 DBG_ERR(("A: A(%d) E(%08x) XDI out of entities",
603 e->adapter->adapter_nr, e));
604
605 e->e.Id = 0;
606 e->e.ReqCh = 0;
607 e->e.RcCh = 0;
608 e->e.Ind = 0;
609 e->e.IndCh = 0;
610 e->e.XNum = 0;
611 e->e.RNum = 0;
612 e->e.callback = NULL;
613 e->e.X = NULL;
614 e->e.R = NULL;
615 write_return_code(e, ASSIGN_RC | OUT_OF_RESOURCES);
616 return (-2);
617 } else {
618 e->status |= DIVA_UM_IDI_ASSIGN_PENDING;
619 }
620 }
621
622 return (0);
623}
624
625static int process_idi_rc(divas_um_idi_entity_t *e, byte rc)
626{
627 DBG_TRC(("A(%d) E(%08x) rc(%02x-%02x-%02x)",
628 e->adapter->adapter_nr, e, e->e.Id, rc, e->e.RcCh));
629
630 if (e->status & DIVA_UM_IDI_ASSIGN_PENDING) {
631 e->status &= ~DIVA_UM_IDI_ASSIGN_PENDING;
632 if (rc != ASSIGN_OK) {
633 DBG_ERR(("A: A(%d) E(%08x) ASSIGN failed",
634 e->adapter->adapter_nr, e));
635 e->e.callback = NULL;
636 e->e.Id = 0;
637 e->e.Req = 0;
638 e->e.ReqCh = 0;
639 e->e.Rc = 0;
640 e->e.RcCh = 0;
641 e->e.Ind = 0;
642 e->e.IndCh = 0;
643 e->e.X = NULL;
644 e->e.R = NULL;
645 e->e.XNum = 0;
646 e->e.RNum = 0;
647 }
648 }
649 if ((e->e.Req == REMOVE) && e->e.Id && (rc == 0xff)) {
650 DBG_ERR(("A: A(%d) E(%08x) discard OK in REMOVE",
651 e->adapter->adapter_nr, e));
652 return (0); /* let us do it in the driver */
653 }
654 if ((e->e.Req == REMOVE) && (!e->e.Id)) { /* REMOVE COMPLETE */
655 e->e.callback = NULL;
656 e->e.Id = 0;
657 e->e.Req = 0;
658 e->e.ReqCh = 0;
659 e->e.Rc = 0;
660 e->e.RcCh = 0;
661 e->e.Ind = 0;
662 e->e.IndCh = 0;
663 e->e.X = NULL;
664 e->e.R = NULL;
665 e->e.XNum = 0;
666 e->e.RNum = 0;
667 e->rc_count = 0;
668 }
669 if ((e->e.Req == REMOVE) && (rc != 0xff)) { /* REMOVE FAILED */
670 DBG_ERR(("A: A(%d) E(%08x) REMOVE FAILED",
671 e->adapter->adapter_nr, e));
672 }
673 write_return_code(e, rc);
674
675 return (1);
676}
677
678static int process_idi_ind(divas_um_idi_entity_t *e, byte ind)
679{
680 int do_wakeup = 0;
681
682 if (e->e.complete != 0x02) {
683 diva_um_idi_ind_hdr_t *pind =
684 (diva_um_idi_ind_hdr_t *)
685 diva_data_q_get_segment4write(&e->data);
686 if (pind) {
687 e->e.RNum = 1;
688 e->e.R->P = (byte *)&pind[1];
689 e->e.R->PLength =
690 (word) (diva_data_q_get_max_length(&e->data) -
691 sizeof(*pind));
692 DBG_TRC(("A(%d) E(%08x) ind_1(%02x-%02x-%02x)-[%d-%d]",
693 e->adapter->adapter_nr, e, e->e.Id, ind,
694 e->e.IndCh, e->e.RLength,
695 e->e.R->PLength));
696
697 } else {
698 DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-RNR",
699 e->adapter->adapter_nr, e, e->e.Id, ind,
700 e->e.IndCh));
701 e->e.RNum = 0;
702 e->e.RNR = 1;
703 do_wakeup = 1;
704 }
705 } else {
706 diva_um_idi_ind_hdr_t *pind =
707 (diva_um_idi_ind_hdr_t *) (e->e.R->P);
708
709 DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-[%d]",
710 e->adapter->adapter_nr, e, e->e.Id, ind,
711 e->e.IndCh, e->e.R->PLength));
712
713 pind--;
714 pind->type = DIVA_UM_IDI_IND;
715 pind->hdr.ind.Ind = ind;
716 pind->hdr.ind.IndCh = e->e.IndCh;
717 pind->data_length = e->e.R->PLength;
718 diva_data_q_ack_segment4write(&e->data,
719 (int) (sizeof(*pind) +
720 e->e.R->PLength));
721 do_wakeup = 1;
722 }
723
724 if ((e->status & DIVA_UM_IDI_RC_PENDING) && !e->rc.count) {
725 do_wakeup = 0;
726 }
727
728 return (do_wakeup);
729}
730
731/* --------------------------------------------------------------------------
732 Write return code to the return code queue of entity
733 -------------------------------------------------------------------------- */
734static int write_return_code(divas_um_idi_entity_t *e, byte rc)
735{
736 diva_um_idi_ind_hdr_t *prc;
737
738 if (!(prc =
739 (diva_um_idi_ind_hdr_t *) diva_data_q_get_segment4write(&e->rc)))
740 {
741 DBG_ERR(("A: A(%d) E(%08x) rc(%02x) lost",
742 e->adapter->adapter_nr, e, rc));
743 e->status &= ~DIVA_UM_IDI_RC_PENDING;
744 return (-1);
745 }
746
747 prc->type = DIVA_UM_IDI_IND_RC;
748 prc->hdr.rc.Rc = rc;
749 prc->hdr.rc.RcCh = e->e.RcCh;
750 prc->data_length = 0;
751 diva_data_q_ack_segment4write(&e->rc, sizeof(*prc));
752
753 return (0);
754}
755
756/* --------------------------------------------------------------------------
757 Return amount of entries that can be bead from this entity or
758 -1 if adapter was removed
759 -------------------------------------------------------------------------- */
760int diva_user_mode_idi_ind_ready(void *entity, void *os_handle)
761{
762 divas_um_idi_entity_t *e;
763 diva_um_idi_adapter_t *a;
764 diva_os_spin_lock_magic_t old_irql;
765 int ret;
766
767 if (!entity)
768 return (-1);
769 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "ind_ready");
770 e = (divas_um_idi_entity_t *) entity;
771 a = e->adapter;
772
773 if ((!a) || (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
774 /*
775 Adapter was unloaded
776 */
777 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");
778 return (-1); /* adapter was removed */
779 }
780 if (e->status & DIVA_UM_IDI_REMOVED) {
781 /*
782 entity was removed as result of adapter removal
783 user should assign this entity again
784 */
785 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");
786 return (-1);
787 }
788
789 ret = e->rc.count + e->data.count;
790
791 if ((e->status & DIVA_UM_IDI_RC_PENDING) && !e->rc.count) {
792 ret = 0;
793 }
794
795 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");
796
797 return (ret);
798}
799
800void *diva_um_id_get_os_context(void *entity)
801{
802 return (((divas_um_idi_entity_t *) entity)->os_context);
803}
804
805int divas_um_idi_entity_assigned(void *entity)
806{
807 divas_um_idi_entity_t *e;
808 diva_um_idi_adapter_t *a;
809 int ret;
810 diva_os_spin_lock_magic_t old_irql;
811
812 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "assigned?");
813
814
815 e = (divas_um_idi_entity_t *) entity;
816 if (!e || (!(a = e->adapter)) ||
817 (e->status & DIVA_UM_IDI_REMOVED) ||
818 (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
819 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?");
820 return (0);
821 }
822
823 e->status |= DIVA_UM_IDI_REMOVE_PENDING;
824
825 ret = (e->e.Id || e->rc_count
826 || (e->status & DIVA_UM_IDI_ASSIGN_PENDING));
827
828 DBG_TRC(("Id:%02x, rc_count:%d, status:%08x", e->e.Id, e->rc_count,
829 e->status))
830
831 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?");
832
833 return (ret);
834}
835
836int divas_um_idi_entity_start_remove(void *entity)
837{
838 divas_um_idi_entity_t *e;
839 diva_um_idi_adapter_t *a;
840 diva_os_spin_lock_magic_t old_irql;
841
842 diva_os_enter_spin_lock(&adapter_lock, &old_irql, "start_remove");
843
844 e = (divas_um_idi_entity_t *) entity;
845 if (!e || (!(a = e->adapter)) ||
846 (e->status & DIVA_UM_IDI_REMOVED) ||
847 (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
848 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");
849 return (0);
850 }
851
852 if (e->rc_count) {
853 /*
854 Entity BUSY
855 */
856 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");
857 return (1);
858 }
859
860 if (!e->e.Id) {
861 /*
862 Remove request was already pending, and arrived now
863 */
864 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");
865 return (0); /* REMOVE was pending */
866 }
867
868 /*
869 Now send remove request
870 */
871 e->e.Req = REMOVE;
872 e->e.ReqCh = 0;
873
874 e->rc_count++;
875
876 DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))",
877 e->adapter->adapter_nr, e, e->e.Id, e->e.Req,
878 e->e.ReqCh, e->e.X->PLength));
879
880 if (a->d.request)
881 (*(a->d.request)) (&e->e);
882
883 diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");
884
885 return (0);
886}
diff --git a/drivers/isdn/hardware/eicon/um_idi.h b/drivers/isdn/hardware/eicon/um_idi.h
deleted file mode 100644
index 9aedd9e351a3..000000000000
--- a/drivers/isdn/hardware/eicon/um_idi.h
+++ /dev/null
@@ -1,44 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: um_idi.h,v 1.6 2004/03/21 17:26:01 armin Exp $ */
3
4#ifndef __DIVA_USER_MODE_IDI_CORE_H__
5#define __DIVA_USER_MODE_IDI_CORE_H__
6
7
8/*
9 interface between UM IDI core and OS dependent part
10*/
11int diva_user_mode_idi_init(void);
12void diva_user_mode_idi_finit(void);
13void *divas_um_idi_create_entity(dword adapter_nr, void *file);
14int divas_um_idi_delete_entity(int adapter_nr, void *entity);
15
16typedef int (*divas_um_idi_copy_to_user_fn_t) (void *os_handle,
17 void *dst,
18 const void *src,
19 int length);
20typedef int (*divas_um_idi_copy_from_user_fn_t) (void *os_handle,
21 void *dst,
22 const void *src,
23 int length);
24
25int diva_um_idi_read(void *entity,
26 void *os_handle,
27 void *dst,
28 int max_length, divas_um_idi_copy_to_user_fn_t cp_fn);
29
30int diva_um_idi_write(void *entity,
31 void *os_handle,
32 const void *src,
33 int length, divas_um_idi_copy_from_user_fn_t cp_fn);
34
35int diva_user_mode_idi_ind_ready(void *entity, void *os_handle);
36void *diva_um_id_get_os_context(void *entity);
37int diva_os_get_context_size(void);
38int divas_um_idi_entity_assigned(void *entity);
39int divas_um_idi_entity_start_remove(void *entity);
40
41void diva_um_idi_start_wdog(void *entity);
42void diva_um_idi_stop_wdog(void *entity);
43
44#endif
diff --git a/drivers/isdn/hardware/eicon/um_xdi.h b/drivers/isdn/hardware/eicon/um_xdi.h
deleted file mode 100644
index 1f37aa4efd18..000000000000
--- a/drivers/isdn/hardware/eicon/um_xdi.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: um_xdi.h,v 1.1.2.2 2002/10/02 14:38:38 armin Exp $ */
3
4#ifndef __DIVA_USER_MODE_XDI_H__
5#define __DIVA_USER_MODE_XDI_H__
6
7/*
8 Contains declaratiom of structures shared between application
9 and user mode idi driver
10*/
11
12typedef struct _diva_um_idi_adapter_features {
13 dword type;
14 dword features;
15 dword channels;
16 dword serial_number;
17 char name[128];
18} diva_um_idi_adapter_features_t;
19
20#define DIVA_UM_IDI_REQ_MASK 0x0000FFFF
21#define DIVA_UM_IDI_REQ_TYPE_MASK (~(DIVA_UM_IDI_REQ_MASK))
22#define DIVA_UM_IDI_GET_FEATURES 1 /* trigger features indication */
23#define DIVA_UM_IDI_REQ 2
24#define DIVA_UM_IDI_REQ_TYPE_MAN 0x10000000
25#define DIVA_UM_IDI_REQ_TYPE_SIG 0x20000000
26#define DIVA_UM_IDI_REQ_TYPE_NET 0x30000000
27#define DIVA_UM_IDI_REQ_MAN (DIVA_UM_IDI_REQ | DIVA_UM_IDI_REQ_TYPE_MAN)
28#define DIVA_UM_IDI_REQ_SIG (DIVA_UM_IDI_REQ | DIVA_UM_IDI_REQ_TYPE_SIG)
29#define DIVA_UM_IDI_REQ_NET (DIVA_UM_IDI_REQ | DIVA_UM_IDI_REQ_TYPE_NET)
30/*
31 data_length bytes will follow this structure
32*/
33typedef struct _diva_um_idi_req_hdr {
34 dword type;
35 dword Req;
36 dword ReqCh;
37 dword data_length;
38} diva_um_idi_req_hdr_t;
39
40typedef struct _diva_um_idi_ind_parameters {
41 dword Ind;
42 dword IndCh;
43} diva_um_idi_ind_parameters_t;
44
45typedef struct _diva_um_idi_rc_parameters {
46 dword Rc;
47 dword RcCh;
48} diva_um_idi_rc_parameters_t;
49
50typedef union _diva_um_idi_ind {
51 diva_um_idi_adapter_features_t features;
52 diva_um_idi_ind_parameters_t ind;
53 diva_um_idi_rc_parameters_t rc;
54} diva_um_idi_ind_t;
55
56#define DIVA_UM_IDI_IND_FEATURES 1 /* features indication */
57#define DIVA_UM_IDI_IND 2
58#define DIVA_UM_IDI_IND_RC 3
59/*
60 data_length bytes of data follow
61 this structure
62*/
63typedef struct _diva_um_idi_ind_hdr {
64 dword type;
65 diva_um_idi_ind_t hdr;
66 dword data_length;
67} diva_um_idi_ind_hdr_t;
68
69#endif
diff --git a/drivers/isdn/hardware/eicon/xdi_adapter.h b/drivers/isdn/hardware/eicon/xdi_adapter.h
deleted file mode 100644
index b036e217c659..000000000000
--- a/drivers/isdn/hardware/eicon/xdi_adapter.h
+++ /dev/null
@@ -1,71 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: xdi_adapter.h,v 1.7 2004/03/21 17:26:01 armin Exp $ */
3
4#ifndef __DIVA_OS_XDI_ADAPTER_H__
5#define __DIVA_OS_XDI_ADAPTER_H__
6
7#define DIVAS_XDI_ADAPTER_BUS_PCI 0
8#define DIVAS_XDI_ADAPTER_BUS_ISA 1
9
10typedef struct _divas_pci_card_resources {
11 byte bus;
12 byte func;
13 void *hdev;
14
15 dword bar[8]; /* contains context of appropriate BAR Register */
16 void __iomem *addr[8]; /* same bar, but mapped into memory */
17 dword length[8]; /* bar length */
18 int mem_type_id[MAX_MEM_TYPE];
19 unsigned int qoffset;
20 byte irq;
21} divas_pci_card_resources_t;
22
23typedef union _divas_card_resources {
24 divas_pci_card_resources_t pci;
25} divas_card_resources_t;
26
27struct _diva_os_xdi_adapter;
28typedef int (*diva_init_card_proc_t)(struct _diva_os_xdi_adapter *a);
29typedef int (*diva_cmd_card_proc_t)(struct _diva_os_xdi_adapter *a,
30 diva_xdi_um_cfg_cmd_t *data,
31 int length);
32typedef void (*diva_xdi_clear_interrupts_proc_t)(struct
33 _diva_os_xdi_adapter *);
34
35#define DIVA_XDI_MBOX_BUSY 1
36#define DIVA_XDI_MBOX_WAIT_XLOG 2
37
38typedef struct _xdi_mbox_t {
39 dword status;
40 diva_xdi_um_cfg_cmd_data_t cmd_data;
41 dword data_length;
42 void *data;
43} xdi_mbox_t;
44
45typedef struct _diva_os_idi_adapter_interface {
46 diva_init_card_proc_t cleanup_adapter_proc;
47 diva_cmd_card_proc_t cmd_proc;
48} diva_os_idi_adapter_interface_t;
49
50typedef struct _diva_os_xdi_adapter {
51 struct list_head link;
52 int CardIndex;
53 int CardOrdinal;
54 int controller; /* number of this controller */
55 int Bus; /* PCI, ISA, ... */
56 divas_card_resources_t resources;
57 char port_name[24];
58 ISDN_ADAPTER xdi_adapter;
59 xdi_mbox_t xdi_mbox;
60 diva_os_idi_adapter_interface_t interface;
61 struct _diva_os_xdi_adapter *slave_adapters[3];
62 void *slave_list;
63 void *proc_adapter_dir; /* adapterX proc entry */
64 void *proc_info; /* info proc entry */
65 void *proc_grp_opt; /* group_optimization */
66 void *proc_d_l1_down; /* dynamic_l1_down */
67 volatile diva_xdi_clear_interrupts_proc_t clear_interrupts_proc;
68 dword dsp_mask;
69} diva_os_xdi_adapter_t;
70
71#endif
diff --git a/drivers/isdn/hardware/eicon/xdi_msg.h b/drivers/isdn/hardware/eicon/xdi_msg.h
deleted file mode 100644
index 0646079bf466..000000000000
--- a/drivers/isdn/hardware/eicon/xdi_msg.h
+++ /dev/null
@@ -1,128 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* $Id: xdi_msg.h,v 1.1.2.2 2001/02/16 08:40:36 armin Exp $ */
3
4#ifndef __DIVA_XDI_UM_CFG_MESSAGE_H__
5#define __DIVA_XDI_UM_CFG_MESSAGE_H__
6
7/*
8 Definition of messages used to communicate between
9 XDI device driver and user mode configuration utility
10*/
11
12/*
13 As acknowledge one DWORD - card ordinal will be read from the card
14*/
15#define DIVA_XDI_UM_CMD_GET_CARD_ORDINAL 0
16
17/*
18 no acknowledge will be generated, memory block will be written in the
19 memory at given offset
20*/
21#define DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK 1
22
23/*
24 no acknowledge will be genatated, FPGA will be programmed
25*/
26#define DIVA_XDI_UM_CMD_WRITE_FPGA 2
27
28/*
29 As acknowledge block of SDRAM will be read in the user buffer
30*/
31#define DIVA_XDI_UM_CMD_READ_SDRAM 3
32
33/*
34 As acknowledge dword with serial number will be read in the user buffer
35*/
36#define DIVA_XDI_UM_CMD_GET_SERIAL_NR 4
37
38/*
39 As acknowledge struct consisting from 9 dwords with PCI info.
40 dword[0...7] = 8 PCI BARS
41 dword[9] = IRQ
42*/
43#define DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG 5
44
45/*
46 Reset of the board + activation of primary
47 boot loader
48*/
49#define DIVA_XDI_UM_CMD_RESET_ADAPTER 6
50
51/*
52 Called after code download to start adapter
53 at specified address
54 Start does set new set of features due to fact that we not know
55 if protocol features have changed
56*/
57#define DIVA_XDI_UM_CMD_START_ADAPTER 7
58
59/*
60 Stop adapter, called if user
61 wishes to stop adapter without unload
62 of the driver, to reload adapter with
63 different protocol
64*/
65#define DIVA_XDI_UM_CMD_STOP_ADAPTER 8
66
67/*
68 Get state of current adapter
69 Acknowledge is one dword with following values:
70 0 - adapter ready for download
71 1 - adapter running
72 2 - adapter dead
73 3 - out of service, driver should be restarted or hardware problem
74*/
75#define DIVA_XDI_UM_CMD_GET_CARD_STATE 9
76
77/*
78 Reads XLOG entry from the card
79*/
80#define DIVA_XDI_UM_CMD_READ_XLOG_ENTRY 10
81
82/*
83 Set untranslated protocol code features
84*/
85#define DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES 11
86
87typedef struct _diva_xdi_um_cfg_cmd_data_set_features {
88 dword features;
89} diva_xdi_um_cfg_cmd_data_set_features_t;
90
91typedef struct _diva_xdi_um_cfg_cmd_data_start {
92 dword offset;
93 dword features;
94} diva_xdi_um_cfg_cmd_data_start_t;
95
96typedef struct _diva_xdi_um_cfg_cmd_data_write_sdram {
97 dword ram_number;
98 dword offset;
99 dword length;
100} diva_xdi_um_cfg_cmd_data_write_sdram_t;
101
102typedef struct _diva_xdi_um_cfg_cmd_data_write_fpga {
103 dword fpga_number;
104 dword image_length;
105} diva_xdi_um_cfg_cmd_data_write_fpga_t;
106
107typedef struct _diva_xdi_um_cfg_cmd_data_read_sdram {
108 dword ram_number;
109 dword offset;
110 dword length;
111} diva_xdi_um_cfg_cmd_data_read_sdram_t;
112
113typedef union _diva_xdi_um_cfg_cmd_data {
114 diva_xdi_um_cfg_cmd_data_write_sdram_t write_sdram;
115 diva_xdi_um_cfg_cmd_data_write_fpga_t write_fpga;
116 diva_xdi_um_cfg_cmd_data_read_sdram_t read_sdram;
117 diva_xdi_um_cfg_cmd_data_start_t start;
118 diva_xdi_um_cfg_cmd_data_set_features_t features;
119} diva_xdi_um_cfg_cmd_data_t;
120
121typedef struct _diva_xdi_um_cfg_cmd {
122 dword adapter; /* Adapter number 1...N */
123 dword command;
124 diva_xdi_um_cfg_cmd_data_t command_data;
125 dword data_length; /* Plain binary data will follow */
126} diva_xdi_um_cfg_cmd_t;
127
128#endif
diff --git a/drivers/isdn/hardware/eicon/xdi_vers.h b/drivers/isdn/hardware/eicon/xdi_vers.h
deleted file mode 100644
index b3479e59c7c5..000000000000
--- a/drivers/isdn/hardware/eicon/xdi_vers.h
+++ /dev/null
@@ -1,26 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Networks, 2002.
5 *
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
8 *
9 Eicon File Revision : 2.1
10 *
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 *
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
20 *
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26static char diva_xdi_common_code_build[] = "102-52";