aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2009-10-06 08:19:17 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-07 01:43:53 -0400
commit7bb5fdc2fb021e32703ed1ff0269876bde1fa962 (patch)
tree818c29b7ed3ece19165d317050c333bab9f7fadb
parentaaba2b3f8213e1d66e71c351fa7a2b1cbd974d3c (diff)
gigaset: add Kernel CAPI interface (v3)
Add a Kernel CAPI interface to the Gigaset driver. Impact: optional new functionality Signed-off-by: Tilman Schmidt <tilman@imap.cc> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/isdn/README.gigaset34
-rw-r--r--drivers/isdn/gigaset/Kconfig18
-rw-r--r--drivers/isdn/gigaset/Makefile1
-rw-r--r--drivers/isdn/gigaset/capi.c2273
-rw-r--r--drivers/isdn/gigaset/common.c26
-rw-r--r--drivers/isdn/gigaset/ev-layer.c26
-rw-r--r--drivers/isdn/gigaset/gigaset.h7
7 files changed, 2356 insertions, 29 deletions
diff --git a/Documentation/isdn/README.gigaset b/Documentation/isdn/README.gigaset
index f9963103ae3d..0fc9831d7ecb 100644
--- a/Documentation/isdn/README.gigaset
+++ b/Documentation/isdn/README.gigaset
@@ -5,7 +5,7 @@ GigaSet 307x Device Driver
5 ------------ 5 ------------
61.1. Hardware 61.1. Hardware
7 -------- 7 --------
8 This release supports the connection of the Gigaset 307x/417x family of 8 This driver supports the connection of the Gigaset 307x/417x family of
9 ISDN DECT bases via Gigaset M101 Data, Gigaset M105 Data or direct USB 9 ISDN DECT bases via Gigaset M101 Data, Gigaset M105 Data or direct USB
10 connection. The following devices are reported to be compatible: 10 connection. The following devices are reported to be compatible:
11 11
@@ -33,7 +33,7 @@ GigaSet 307x Device Driver
33 http://gigaset307x.sourceforge.net/ 33 http://gigaset307x.sourceforge.net/
34 34
35 We had also reports from users of Gigaset M105 who could use the drivers 35 We had also reports from users of Gigaset M105 who could use the drivers
36 with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.4.) 36 with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.5.)
37 If you have another device that works with our driver, please let us know. 37 If you have another device that works with our driver, please let us know.
38 38
39 Chances of getting an USB device to work are good if the output of 39 Chances of getting an USB device to work are good if the output of
@@ -49,7 +49,7 @@ GigaSet 307x Device Driver
49 -------- 49 --------
50 The driver works with ISDN4linux and so can be used with any software 50 The driver works with ISDN4linux and so can be used with any software
51 which is able to use ISDN4linux for ISDN connections (voice or data). 51 which is able to use ISDN4linux for ISDN connections (voice or data).
52 CAPI4Linux support is planned but not yet available. 52 Experimental Kernel CAPI support is available as a compilation option.
53 53
54 There are some user space tools available at 54 There are some user space tools available at
55 http://sourceforge.net/projects/gigaset307x/ 55 http://sourceforge.net/projects/gigaset307x/
@@ -102,20 +102,28 @@ GigaSet 307x Device Driver
1022.3. ISDN4linux 1022.3. ISDN4linux
103 ---------- 103 ----------
104 This is the "normal" mode of operation. After loading the module you can 104 This is the "normal" mode of operation. After loading the module you can
105 set up the ISDN system just as you'd do with any ISDN card. 105 set up the ISDN system just as you'd do with any ISDN card supported by
106 Your distribution should provide some configuration utility. 106 the ISDN4Linux subsystem. Most distributions provide some configuration
107 If not, you can use some HOWTOs like 107 utility. If not, you can use some HOWTOs like
108 http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html 108 http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html
109 If this doesn't work, because you have some recent device like SX100 where 109 If this doesn't work, because you have some device like SX100 where
110 debug output (see section 3.2.) shows something like this when dialing 110 debug output (see section 3.2.) shows something like this when dialing
111 CMD Received: ERROR 111 CMD Received: ERROR
112 Available Params: 0 112 Available Params: 0
113 Connection State: 0, Response: -1 113 Connection State: 0, Response: -1
114 gigaset_process_response: resp_code -1 in ConState 0 ! 114 gigaset_process_response: resp_code -1 in ConState 0 !
115 Timeout occurred 115 Timeout occurred
116 you might need to use unimodem mode: 116 you might need to use unimodem mode. (see section 2.5.)
117 117
1182.4. Unimodem mode 1182.4. CAPI
119 ----
120 If the driver is compiled with CAPI support (kernel configuration option
121 GIGASET_CAPI, experimental) it can also be used with CAPI 2.0 kernel and
122 user space applications. ISDN4Linux is supported in this configuration
123 via the capidrv compatibility driver. The kernel module capidrv.ko must
124 be loaded explicitly ("modprobe capidrv") if needed.
125
1262.5. Unimodem mode
119 ------------- 127 -------------
120 This is needed for some devices [e.g. SX100] as they have problems with 128 This is needed for some devices [e.g. SX100] as they have problems with
121 the "normal" commands. 129 the "normal" commands.
@@ -160,7 +168,7 @@ GigaSet 307x Device Driver
160 configuration file like /etc/modprobe.conf.local, 168 configuration file like /etc/modprobe.conf.local,
161 using that should be preferred. 169 using that should be preferred.
162 170
1632.5. Call-ID (CID) mode 1712.6. Call-ID (CID) mode
164 ------------------ 172 ------------------
165 Call-IDs are numbers used to tag commands to, and responses from, the 173 Call-IDs are numbers used to tag commands to, and responses from, the
166 Gigaset base in order to support the simultaneous handling of multiple 174 Gigaset base in order to support the simultaneous handling of multiple
@@ -188,7 +196,7 @@ GigaSet 307x Device Driver
188 You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode 196 You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode
189 setting (ttyGxy is ttyGU0 or ttyGB0). 197 setting (ttyGxy is ttyGU0 or ttyGB0).
190 198
1912.6. Unregistered Wireless Devices (M101/M105) 1992.7. Unregistered Wireless Devices (M101/M105)
192 ----------------------------------------- 200 -----------------------------------------
193 The main purpose of the ser_gigaset and usb_gigaset drivers is to allow 201 The main purpose of the ser_gigaset and usb_gigaset drivers is to allow
194 the M101 and M105 wireless devices to be used as ISDN devices for ISDN 202 the M101 and M105 wireless devices to be used as ISDN devices for ISDN
@@ -228,7 +236,7 @@ GigaSet 307x Device Driver
228 You have two or more DECT data adapters (M101/M105) and only the 236 You have two or more DECT data adapters (M101/M105) and only the
229 first one you turn on works. 237 first one you turn on works.
230 Solution: 238 Solution:
231 Select Unimodem mode for all DECT data adapters. (see section 2.4.) 239 Select Unimodem mode for all DECT data adapters. (see section 2.5.)
232 240
233 Problem: 241 Problem:
234 Messages like this: 242 Messages like this:
@@ -236,7 +244,7 @@ GigaSet 307x Device Driver
236 appear in your syslog. 244 appear in your syslog.
237 Solution: 245 Solution:
238 Check whether your M10x wireless device is correctly registered to the 246 Check whether your M10x wireless device is correctly registered to the
239 Gigaset base. (see section 2.6.) 247 Gigaset base. (see section 2.7.)
240 248
2413.2. Telling the driver to provide more information 2493.2. Telling the driver to provide more information
242 ---------------------------------------------- 250 ----------------------------------------------
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index 6fd2dc1e97fb..dcefedc7044a 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -10,20 +10,32 @@ menuconfig ISDN_DRV_GIGASET
10 If you have one of these devices, say M here and for at least 10 If you have one of these devices, say M here and for at least
11 one of the connection specific parts that follow. 11 one of the connection specific parts that follow.
12 This will build a module called "gigaset". 12 This will build a module called "gigaset".
13 Note: If you build the ISDN4Linux subsystem (ISDN_I4L) 13 Note: If you build your ISDN subsystem (ISDN_CAPI or ISDN_I4L)
14 as a module, you have to build this driver as a module too, 14 as a module, you have to build this driver as a module too,
15 otherwise the Gigaset device won't show up as an ISDN device. 15 otherwise the Gigaset device won't show up as an ISDN device.
16 16
17if ISDN_DRV_GIGASET 17if ISDN_DRV_GIGASET
18 18
19config GIGASET_CAPI
20 bool "Gigaset CAPI support (EXPERIMENTAL)"
21 depends on EXPERIMENTAL
22 depends on ISDN_CAPI='y'||(ISDN_CAPI='m'&&ISDN_DRV_GIGASET='m')
23 default ISDN_I4L='n'
24 help
25 Build the Gigaset driver as a CAPI 2.0 driver interfacing with
26 the Kernel CAPI subsystem. To use it with the old ISDN4Linux
27 subsystem you'll have to enable the capidrv glue driver.
28 (select ISDN_CAPI_CAPIDRV.)
29 Say N to build the old native ISDN4Linux variant.
30
19config GIGASET_I4L 31config GIGASET_I4L
20 bool 32 bool
21 depends on ISDN_I4L='y'||(ISDN_I4L='m'&&ISDN_DRV_GIGASET='m') 33 depends on ISDN_I4L='y'||(ISDN_I4L='m'&&ISDN_DRV_GIGASET='m')
22 default y 34 default !GIGASET_CAPI
23 35
24config GIGASET_DUMMYLL 36config GIGASET_DUMMYLL
25 bool 37 bool
26 default !GIGASET_I4L 38 default !GIGASET_CAPI&&!GIGASET_I4L
27 39
28config GIGASET_BASE 40config GIGASET_BASE
29 tristate "Gigaset base station support" 41 tristate "Gigaset base station support"
diff --git a/drivers/isdn/gigaset/Makefile b/drivers/isdn/gigaset/Makefile
index d429202ba8ef..c453b72272a0 100644
--- a/drivers/isdn/gigaset/Makefile
+++ b/drivers/isdn/gigaset/Makefile
@@ -1,4 +1,5 @@
1gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o 1gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o
2gigaset-$(CONFIG_GIGASET_CAPI) += capi.o
2gigaset-$(CONFIG_GIGASET_I4L) += i4l.o 3gigaset-$(CONFIG_GIGASET_I4L) += i4l.o
3gigaset-$(CONFIG_GIGASET_DUMMYLL) += dummyll.o 4gigaset-$(CONFIG_GIGASET_DUMMYLL) += dummyll.o
4usb_gigaset-y := usb-gigaset.o 5usb_gigaset-y := usb-gigaset.o
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
new file mode 100644
index 000000000000..c276a925b36f
--- /dev/null
+++ b/drivers/isdn/gigaset/capi.c
@@ -0,0 +1,2273 @@
1/*
2 * Kernel CAPI interface for the Gigaset driver
3 *
4 * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
5 *
6 * =====================================================================
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 * =====================================================================
12 */
13
14#include "gigaset.h"
15#include <linux/ctype.h>
16#include <linux/isdn/capilli.h>
17#include <linux/isdn/capicmd.h>
18#include <linux/isdn/capiutil.h>
19
20/* missing from kernelcapi.h */
21#define CapiNcpiNotSupportedByProtocol 0x0001
22#define CapiFlagsNotSupportedByProtocol 0x0002
23#define CapiAlertAlreadySent 0x0003
24#define CapiFacilitySpecificFunctionNotSupported 0x3011
25
26/* missing from capicmd.h */
27#define CAPI_CONNECT_IND_BASELEN (CAPI_MSG_BASELEN+4+2+8*1)
28#define CAPI_CONNECT_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN+4+3*1)
29#define CAPI_CONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN+4+1)
30#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN+4+1)
31#define CAPI_DATA_B3_REQ_LEN64 (CAPI_MSG_BASELEN+4+4+2+2+2+8)
32#define CAPI_DATA_B3_CONF_LEN (CAPI_MSG_BASELEN+4+2+2)
33#define CAPI_DISCONNECT_IND_LEN (CAPI_MSG_BASELEN+4+2)
34#define CAPI_DISCONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN+4+2+1)
35#define CAPI_FACILITY_CONF_BASELEN (CAPI_MSG_BASELEN+4+2+2+1)
36/* most _CONF messages contain only Controller/PLCI/NCCI and Info parameters */
37#define CAPI_STDCONF_LEN (CAPI_MSG_BASELEN+4+2)
38
39#define CAPI_FACILITY_HANDSET 0x0000
40#define CAPI_FACILITY_DTMF 0x0001
41#define CAPI_FACILITY_V42BIS 0x0002
42#define CAPI_FACILITY_SUPPSVC 0x0003
43#define CAPI_FACILITY_WAKEUP 0x0004
44#define CAPI_FACILITY_LI 0x0005
45
46#define CAPI_SUPPSVC_GETSUPPORTED 0x0000
47
48/* missing from capiutil.h */
49#define CAPIMSG_PLCI_PART(m) CAPIMSG_U8(m, 9)
50#define CAPIMSG_NCCI_PART(m) CAPIMSG_U16(m, 10)
51#define CAPIMSG_HANDLE_REQ(m) CAPIMSG_U16(m, 18) /* DATA_B3_REQ/_IND only! */
52#define CAPIMSG_FLAGS(m) CAPIMSG_U16(m, 20)
53#define CAPIMSG_SETCONTROLLER(m, contr) capimsg_setu8(m, 8, contr)
54#define CAPIMSG_SETPLCI_PART(m, plci) capimsg_setu8(m, 9, plci)
55#define CAPIMSG_SETNCCI_PART(m, ncci) capimsg_setu16(m, 10, ncci)
56#define CAPIMSG_SETFLAGS(m, flags) capimsg_setu16(m, 20, flags)
57
58/* parameters with differing location in DATA_B3_CONF/_RESP: */
59#define CAPIMSG_SETHANDLE_CONF(m, handle) capimsg_setu16(m, 12, handle)
60#define CAPIMSG_SETINFO_CONF(m, info) capimsg_setu16(m, 14, info)
61
62/* Flags (DATA_B3_REQ/_IND) */
63#define CAPI_FLAGS_DELIVERY_CONFIRMATION 0x04
64#define CAPI_FLAGS_RESERVED (~0x1f)
65
66/* buffer sizes */
67#define MAX_BC_OCTETS 11
68#define MAX_HLC_OCTETS 3
69#define MAX_NUMBER_DIGITS 20
70#define MAX_FMT_IE_LEN 20
71
72/* values for gigaset_capi_appl.connected */
73#define APCONN_NONE 0 /* inactive/listening */
74#define APCONN_SETUP 1 /* connecting */
75#define APCONN_ACTIVE 2 /* B channel up */
76
77/* registered application data structure */
78struct gigaset_capi_appl {
79 struct list_head ctrlist;
80 struct gigaset_capi_appl *bcnext;
81 u16 id;
82 u16 nextMessageNumber;
83 u32 listenInfoMask;
84 u32 listenCIPmask;
85 int connected;
86};
87
88/* CAPI specific controller data structure */
89struct gigaset_capi_ctr {
90 struct capi_ctr ctr;
91 struct list_head appls;
92 struct sk_buff_head sendqueue;
93 atomic_t sendqlen;
94 /* two _cmsg structures possibly used concurrently: */
95 _cmsg hcmsg; /* for message composition triggered from hardware */
96 _cmsg acmsg; /* for dissection of messages sent from application */
97 u8 bc_buf[MAX_BC_OCTETS+1];
98 u8 hlc_buf[MAX_HLC_OCTETS+1];
99 u8 cgpty_buf[MAX_NUMBER_DIGITS+3];
100 u8 cdpty_buf[MAX_NUMBER_DIGITS+2];
101};
102
103/* CIP Value table (from CAPI 2.0 standard, ch. 6.1) */
104static struct {
105 u8 *bc;
106 u8 *hlc;
107} cip2bchlc[] = {
108 [1] = { "8090A3", NULL },
109 /* Speech (A-law) */
110 [2] = { "8890", NULL },
111 /* Unrestricted digital information */
112 [3] = { "8990", NULL },
113 /* Restricted digital information */
114 [4] = { "9090A3", NULL },
115 /* 3,1 kHz audio (A-law) */
116 [5] = { "9190", NULL },
117 /* 7 kHz audio */
118 [6] = { "9890", NULL },
119 /* Video */
120 [7] = { "88C0C6E6", NULL },
121 /* Packet mode */
122 [8] = { "8890218F", NULL },
123 /* 56 kbit/s rate adaptation */
124 [9] = { "9190A5", NULL },
125 /* Unrestricted digital information with tones/announcements */
126 [16] = { "8090A3", "9181" },
127 /* Telephony */
128 [17] = { "9090A3", "9184" },
129 /* Group 2/3 facsimile */
130 [18] = { "8890", "91A1" },
131 /* Group 4 facsimile Class 1 */
132 [19] = { "8890", "91A4" },
133 /* Teletex service basic and mixed mode
134 and Group 4 facsimile service Classes II and III */
135 [20] = { "8890", "91A8" },
136 /* Teletex service basic and processable mode */
137 [21] = { "8890", "91B1" },
138 /* Teletex service basic mode */
139 [22] = { "8890", "91B2" },
140 /* International interworking for Videotex */
141 [23] = { "8890", "91B5" },
142 /* Telex */
143 [24] = { "8890", "91B8" },
144 /* Message Handling Systems in accordance with X.400 */
145 [25] = { "8890", "91C1" },
146 /* OSI application in accordance with X.200 */
147 [26] = { "9190A5", "9181" },
148 /* 7 kHz telephony */
149 [27] = { "9190A5", "916001" },
150 /* Video telephony, first connection */
151 [28] = { "8890", "916002" },
152 /* Video telephony, second connection */
153};
154
155/*
156 * helper functions
157 * ================
158 */
159
160/*
161 * emit unsupported parameter warning
162 */
163static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
164 char *msgname, char *paramname)
165{
166 if (param && *param)
167 dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
168 msgname, paramname);
169}
170
171static inline void ignore_cmstruct_param(struct cardstate *cs, _cmstruct param,
172 char *msgname, char *paramname)
173{
174 if (param != CAPI_DEFAULT)
175 dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
176 msgname, paramname);
177}
178
179/*
180 * check for legal hex digit
181 */
182static inline int ishexdigit(char c)
183{
184 if (c >= '0' && c <= '9')
185 return 1;
186 if (c >= 'A' && c <= 'F')
187 return 1;
188 if (c >= 'a' && c <= 'f')
189 return 1;
190 return 0;
191}
192
193/*
194 * convert hex to binary
195 */
196static inline u8 hex2bin(char c)
197{
198 int result = c & 0x0f;
199 if (c & 0x40)
200 result += 9;
201 return result;
202}
203
204/*
205 * convert an IE from Gigaset hex string to ETSI binary representation
206 * including length byte
207 * return value: result length, -1 on error
208 */
209static int encode_ie(char *in, u8 *out, int maxlen)
210{
211 int l = 0;
212 while (*in) {
213 if (!ishexdigit(in[0]) || !ishexdigit(in[1]) || l >= maxlen)
214 return -1;
215 out[++l] = (hex2bin(in[0]) << 4) + hex2bin(in[1]);
216 in += 2;
217 }
218 out[0] = l;
219 return l;
220}
221
222/*
223 * convert an IE from ETSI binary representation including length byte
224 * to Gigaset hex string
225 */
226static void decode_ie(u8 *in, char *out)
227{
228 int i = *in;
229 while (i-- > 0) {
230 /* ToDo: conversion to upper case necessary? */
231 *out++ = toupper(hex_asc_hi(*++in));
232 *out++ = toupper(hex_asc_lo(*in));
233 }
234}
235
236/*
237 * retrieve application data structure for an application ID
238 */
239static inline struct gigaset_capi_appl *
240get_appl(struct gigaset_capi_ctr *iif, u16 appl)
241{
242 struct gigaset_capi_appl *ap;
243
244 list_for_each_entry(ap, &iif->appls, ctrlist)
245 if (ap->id == appl)
246 return ap;
247 return NULL;
248}
249
250/*
251 * dump CAPI message to kernel messages for debugging
252 */
253static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p)
254{
255#ifdef CONFIG_GIGASET_DEBUG
256 _cdebbuf *cdb;
257
258 if (!(gigaset_debuglevel & level))
259 return;
260
261 cdb = capi_cmsg2str(p);
262 if (cdb) {
263 gig_dbg(level, "%s: [%d] %s", tag, p->ApplId, cdb->buf);
264 cdebbuf_free(cdb);
265 } else {
266 gig_dbg(level, "%s: [%d] %s", tag, p->ApplId,
267 capi_cmd2str(p->Command, p->Subcommand));
268 }
269#endif
270}
271
272static inline void dump_rawmsg(enum debuglevel level, const char *tag,
273 unsigned char *data)
274{
275#ifdef CONFIG_GIGASET_DEBUG
276 char *dbgline;
277 int i, l;
278
279 if (!(gigaset_debuglevel & level))
280 return;
281
282 l = CAPIMSG_LEN(data);
283 if (l < 12) {
284 gig_dbg(level, "%s: ??? LEN=%04d", tag, l);
285 return;
286 }
287 gig_dbg(level, "%s: 0x%02x:0x%02x: ID=%03d #0x%04x LEN=%04d NCCI=0x%x",
288 tag, CAPIMSG_COMMAND(data), CAPIMSG_SUBCOMMAND(data),
289 CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
290 CAPIMSG_CONTROL(data));
291 l -= 12;
292 dbgline = kmalloc(3*l, GFP_ATOMIC);
293 if (!dbgline)
294 return;
295 for (i = 0; i < l; i++) {
296 dbgline[3*i] = hex_asc_hi(data[12+i]);
297 dbgline[3*i+1] = hex_asc_lo(data[12+i]);
298 dbgline[3*i+2] = ' ';
299 }
300 dbgline[3*l-1] = '\0';
301 gig_dbg(level, " %s", dbgline);
302 kfree(dbgline);
303 if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
304 (CAPIMSG_SUBCOMMAND(data) == CAPI_REQ ||
305 CAPIMSG_SUBCOMMAND(data) == CAPI_IND) &&
306 CAPIMSG_DATALEN(data) > 0) {
307 l = CAPIMSG_DATALEN(data);
308 dbgline = kmalloc(3*l, GFP_ATOMIC);
309 if (!dbgline)
310 return;
311 data += CAPIMSG_LEN(data);
312 for (i = 0; i < l; i++) {
313 dbgline[3*i] = hex_asc_hi(data[i]);
314 dbgline[3*i+1] = hex_asc_lo(data[i]);
315 dbgline[3*i+2] = ' ';
316 }
317 dbgline[3*l-1] = '\0';
318 gig_dbg(level, " %s", dbgline);
319 kfree(dbgline);
320 }
321#endif
322}
323
324/*
325 * format CAPI IE as string
326 */
327
328static const char *format_ie(const char *ie)
329{
330 static char result[3*MAX_FMT_IE_LEN];
331 int len, count;
332 char *pout = result;
333
334 if (!ie)
335 return "NULL";
336
337 count = len = ie[0];
338 if (count > MAX_FMT_IE_LEN)
339 count = MAX_FMT_IE_LEN-1;
340 while (count--) {
341 *pout++ = hex_asc_hi(*++ie);
342 *pout++ = hex_asc_lo(*ie);
343 *pout++ = ' ';
344 }
345 if (len > MAX_FMT_IE_LEN) {
346 *pout++ = '.';
347 *pout++ = '.';
348 *pout++ = '.';
349 }
350 *--pout = 0;
351 return result;
352}
353
354
355/*
356 * driver interface functions
357 * ==========================
358 */
359
360/**
361 * gigaset_skb_sent() - acknowledge transmission of outgoing skb
362 * @bcs: B channel descriptor structure.
363 * @skb: sent data.
364 *
365 * Called by hardware module {bas,ser,usb}_gigaset when the data in a
366 * skb has been successfully sent, for signalling completion to the LL.
367 */
368void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
369{
370 struct cardstate *cs = bcs->cs;
371 struct gigaset_capi_ctr *iif = cs->iif;
372 struct gigaset_capi_appl *ap = bcs->ap;
373 struct sk_buff *cskb;
374 u16 flags;
375
376 /* update statistics */
377 ++bcs->trans_up;
378
379 if (!ap) {
380 dev_err(cs->dev, "%s: no application\n", __func__);
381 return;
382 }
383
384 /* don't send further B3 messages if disconnected */
385 if (ap->connected < APCONN_ACTIVE) {
386 gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
387 return;
388 }
389
390 /* ToDo: honor unset "delivery confirmation" bit */
391 flags = CAPIMSG_FLAGS(dskb->head);
392
393 /* build DATA_B3_CONF message */
394 cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
395 if (!cskb) {
396 dev_err(cs->dev, "%s: out of memory\n", __func__);
397 return;
398 }
399 /* frequent message, avoid _cmsg overhead */
400 CAPIMSG_SETLEN(cskb->data, CAPI_DATA_B3_CONF_LEN);
401 CAPIMSG_SETAPPID(cskb->data, ap->id);
402 CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3);
403 CAPIMSG_SETSUBCOMMAND(cskb->data, CAPI_CONF);
404 CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(dskb->head));
405 CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr);
406 CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1);
407 CAPIMSG_SETNCCI_PART(cskb->data, 1);
408 CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(dskb->head));
409 if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION)
410 CAPIMSG_SETINFO_CONF(cskb->data,
411 CapiFlagsNotSupportedByProtocol);
412 else
413 CAPIMSG_SETINFO_CONF(cskb->data, CAPI_NOERROR);
414
415 /* emit message */
416 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_CONF", cskb->data);
417 capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
418}
419EXPORT_SYMBOL_GPL(gigaset_skb_sent);
420
421/**
422 * gigaset_skb_rcvd() - pass received skb to LL
423 * @bcs: B channel descriptor structure.
424 * @skb: received data.
425 *
426 * Called by hardware module {bas,ser,usb}_gigaset when user data has
427 * been successfully received, for passing to the LL.
428 * Warning: skb must not be accessed anymore!
429 */
430void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
431{
432 struct cardstate *cs = bcs->cs;
433 struct gigaset_capi_ctr *iif = cs->iif;
434 struct gigaset_capi_appl *ap = bcs->ap;
435 int len = skb->len;
436
437 /* update statistics */
438 bcs->trans_down++;
439
440 if (!ap) {
441 dev_err(cs->dev, "%s: no application\n", __func__);
442 return;
443 }
444
445 /* don't send further B3 messages if disconnected */
446 if (ap->connected < APCONN_ACTIVE) {
447 gig_dbg(DEBUG_LLDATA, "disconnected, discarding data");
448 dev_kfree_skb(skb);
449 return;
450 }
451
452 /*
453 * prepend DATA_B3_IND message to payload
454 * Parameters: NCCI = 1, all others 0/unused
455 * frequent message, avoid _cmsg overhead
456 */
457 skb_push(skb, CAPI_DATA_B3_REQ_LEN);
458 CAPIMSG_SETLEN(skb->data, CAPI_DATA_B3_REQ_LEN);
459 CAPIMSG_SETAPPID(skb->data, ap->id);
460 CAPIMSG_SETCOMMAND(skb->data, CAPI_DATA_B3);
461 CAPIMSG_SETSUBCOMMAND(skb->data, CAPI_IND);
462 CAPIMSG_SETMSGID(skb->data, ap->nextMessageNumber++);
463 CAPIMSG_SETCONTROLLER(skb->data, iif->ctr.cnr);
464 CAPIMSG_SETPLCI_PART(skb->data, bcs->channel + 1);
465 CAPIMSG_SETNCCI_PART(skb->data, 1);
466 /* Data parameter not used */
467 CAPIMSG_SETDATALEN(skb->data, len);
468 /* Data handle parameter not used */
469 CAPIMSG_SETFLAGS(skb->data, 0);
470 /* Data64 parameter not present */
471
472 /* emit message */
473 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_IND", skb->data);
474 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
475}
476EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
477
478/**
479 * gigaset_isdn_rcv_err() - signal receive error
480 * @bcs: B channel descriptor structure.
481 *
482 * Called by hardware module {bas,ser,usb}_gigaset when a receive error
483 * has occurred, for signalling to the LL.
484 */
485void gigaset_isdn_rcv_err(struct bc_state *bcs)
486{
487 /* if currently ignoring packets, just count down */
488 if (bcs->ignore) {
489 bcs->ignore--;
490 return;
491 }
492
493 /* update statistics */
494 bcs->corrupted++;
495
496 /* ToDo: signal error -> LL */
497}
498EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
499
500/**
501 * gigaset_isdn_icall() - signal incoming call
502 * @at_state: connection state structure.
503 *
504 * Called by main module at tasklet level to notify the LL that an incoming
505 * call has been received. @at_state contains the parameters of the call.
506 *
507 * Return value: call disposition (ICALL_*)
508 */
509int gigaset_isdn_icall(struct at_state_t *at_state)
510{
511 struct cardstate *cs = at_state->cs;
512 struct bc_state *bcs = at_state->bcs;
513 struct gigaset_capi_ctr *iif = cs->iif;
514 struct gigaset_capi_appl *ap;
515 u32 actCIPmask;
516 struct sk_buff *skb;
517 unsigned int msgsize;
518 int i;
519
520 /*
521 * ToDo: signal calls without a free B channel, too
522 * (requires a u8 handle for the at_state structure that can
523 * be stored in the PLCI and used in the CONNECT_RESP message
524 * handler to retrieve it)
525 */
526 if (!bcs)
527 return ICALL_IGNORE;
528
529 /* prepare CONNECT_IND message, using B channel number as PLCI */
530 capi_cmsg_header(&iif->hcmsg, 0, CAPI_CONNECT, CAPI_IND, 0,
531 iif->ctr.cnr | ((bcs->channel + 1) << 8));
532
533 /* minimum size, all structs empty */
534 msgsize = CAPI_CONNECT_IND_BASELEN;
535
536 /* Bearer Capability (mandatory) */
537 if (at_state->str_var[STR_ZBC]) {
538 /* pass on BC from Gigaset */
539 if (encode_ie(at_state->str_var[STR_ZBC], iif->bc_buf,
540 MAX_BC_OCTETS) < 0) {
541 dev_warn(cs->dev, "RING ignored - bad BC %s\n",
542 at_state->str_var[STR_ZBC]);
543 return ICALL_IGNORE;
544 }
545
546 /* look up corresponding CIP value */
547 iif->hcmsg.CIPValue = 0; /* default if nothing found */
548 for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
549 if (cip2bchlc[i].bc != NULL &&
550 cip2bchlc[i].hlc == NULL &&
551 !strcmp(cip2bchlc[i].bc,
552 at_state->str_var[STR_ZBC])) {
553 iif->hcmsg.CIPValue = i;
554 break;
555 }
556 } else {
557 /* no BC (internal call): assume CIP 1 (speech, A-law) */
558 iif->hcmsg.CIPValue = 1;
559 encode_ie(cip2bchlc[1].bc, iif->bc_buf, MAX_BC_OCTETS);
560 }
561 iif->hcmsg.BC = iif->bc_buf;
562 msgsize += iif->hcmsg.BC[0];
563
564 /* High Layer Compatibility (optional) */
565 if (at_state->str_var[STR_ZHLC]) {
566 /* pass on HLC from Gigaset */
567 if (encode_ie(at_state->str_var[STR_ZHLC], iif->hlc_buf,
568 MAX_HLC_OCTETS) < 0) {
569 dev_warn(cs->dev, "RING ignored - bad HLC %s\n",
570 at_state->str_var[STR_ZHLC]);
571 return ICALL_IGNORE;
572 }
573 iif->hcmsg.HLC = iif->hlc_buf;
574 msgsize += iif->hcmsg.HLC[0];
575
576 /* look up corresponding CIP value */
577 /* keep BC based CIP value if none found */
578 if (at_state->str_var[STR_ZBC])
579 for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
580 if (cip2bchlc[i].hlc != NULL &&
581 !strcmp(cip2bchlc[i].hlc,
582 at_state->str_var[STR_ZHLC]) &&
583 !strcmp(cip2bchlc[i].bc,
584 at_state->str_var[STR_ZBC])) {
585 iif->hcmsg.CIPValue = i;
586 break;
587 }
588 }
589
590 /* Called Party Number (optional) */
591 if (at_state->str_var[STR_ZCPN]) {
592 i = strlen(at_state->str_var[STR_ZCPN]);
593 if (i > MAX_NUMBER_DIGITS) {
594 dev_warn(cs->dev, "RING ignored - bad number %s\n",
595 at_state->str_var[STR_ZBC]);
596 return ICALL_IGNORE;
597 }
598 iif->cdpty_buf[0] = i + 1;
599 iif->cdpty_buf[1] = 0x80; /* type / numbering plan unknown */
600 memcpy(iif->cdpty_buf+2, at_state->str_var[STR_ZCPN], i);
601 iif->hcmsg.CalledPartyNumber = iif->cdpty_buf;
602 msgsize += iif->hcmsg.CalledPartyNumber[0];
603 }
604
605 /* Calling Party Number (optional) */
606 if (at_state->str_var[STR_NMBR]) {
607 i = strlen(at_state->str_var[STR_NMBR]);
608 if (i > MAX_NUMBER_DIGITS) {
609 dev_warn(cs->dev, "RING ignored - bad number %s\n",
610 at_state->str_var[STR_ZBC]);
611 return ICALL_IGNORE;
612 }
613 iif->cgpty_buf[0] = i + 2;
614 iif->cgpty_buf[1] = 0x00; /* type / numbering plan unknown */
615 iif->cgpty_buf[2] = 0x80; /* pres. allowed, not screened */
616 memcpy(iif->cgpty_buf+3, at_state->str_var[STR_NMBR], i);
617 iif->hcmsg.CallingPartyNumber = iif->cgpty_buf;
618 msgsize += iif->hcmsg.CallingPartyNumber[0];
619 }
620
621 /* remaining parameters (not supported, always left NULL):
622 * - CalledPartySubaddress
623 * - CallingPartySubaddress
624 * - AdditionalInfo
625 * - BChannelinformation
626 * - Keypadfacility
627 * - Useruserdata
628 * - Facilitydataarray
629 */
630
631 gig_dbg(DEBUG_CMD, "icall: PLCI %x CIP %d BC %s",
632 iif->hcmsg.adr.adrPLCI, iif->hcmsg.CIPValue,
633 format_ie(iif->hcmsg.BC));
634 gig_dbg(DEBUG_CMD, "icall: HLC %s",
635 format_ie(iif->hcmsg.HLC));
636 gig_dbg(DEBUG_CMD, "icall: CgPty %s",
637 format_ie(iif->hcmsg.CallingPartyNumber));
638 gig_dbg(DEBUG_CMD, "icall: CdPty %s",
639 format_ie(iif->hcmsg.CalledPartyNumber));
640
641 /* scan application list for matching listeners */
642 bcs->ap = NULL;
643 actCIPmask = 1 | (1 << iif->hcmsg.CIPValue);
644 list_for_each_entry(ap, &iif->appls, ctrlist)
645 if (actCIPmask & ap->listenCIPmask) {
646 /* build CONNECT_IND message for this application */
647 iif->hcmsg.ApplId = ap->id;
648 iif->hcmsg.Messagenumber = ap->nextMessageNumber++;
649
650 skb = alloc_skb(msgsize, GFP_ATOMIC);
651 if (!skb) {
652 dev_err(cs->dev, "%s: out of memory\n",
653 __func__);
654 break;
655 }
656 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
657 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
658
659 /* add to listeners on this B channel, update state */
660 ap->bcnext = bcs->ap;
661 bcs->ap = ap;
662 bcs->chstate |= CHS_NOTIFY_LL;
663 ap->connected = APCONN_SETUP;
664
665 /* emit message */
666 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
667 }
668
669 /*
670 * Return "accept" if any listeners.
671 * Gigaset will send ALERTING.
672 * There doesn't seem to be a way to avoid this.
673 */
674 return bcs->ap ? ICALL_ACCEPT : ICALL_IGNORE;
675}
676
677/*
678 * send a DISCONNECT_IND message to an application
679 * does not sleep, clobbers the controller's hcmsg structure
680 */
681static void send_disconnect_ind(struct bc_state *bcs,
682 struct gigaset_capi_appl *ap, u16 reason)
683{
684 struct cardstate *cs = bcs->cs;
685 struct gigaset_capi_ctr *iif = cs->iif;
686 struct sk_buff *skb;
687
688 if (ap->connected == APCONN_NONE)
689 return;
690
691 capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT, CAPI_IND,
692 ap->nextMessageNumber++,
693 iif->ctr.cnr | ((bcs->channel + 1) << 8));
694 iif->hcmsg.Reason = reason;
695 skb = alloc_skb(CAPI_DISCONNECT_IND_LEN, GFP_ATOMIC);
696 if (!skb) {
697 dev_err(cs->dev, "%s: out of memory\n", __func__);
698 return;
699 }
700 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN));
701 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
702 ap->connected = APCONN_NONE;
703 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
704}
705
706/*
707 * send a DISCONNECT_B3_IND message to an application
708 * Parameters: NCCI = 1, NCPI empty, Reason_B3 = 0
709 * does not sleep, clobbers the controller's hcmsg structure
710 */
711static void send_disconnect_b3_ind(struct bc_state *bcs,
712 struct gigaset_capi_appl *ap)
713{
714 struct cardstate *cs = bcs->cs;
715 struct gigaset_capi_ctr *iif = cs->iif;
716 struct sk_buff *skb;
717
718 /* nothing to do if no logical connection active */
719 if (ap->connected < APCONN_ACTIVE)
720 return;
721 ap->connected = APCONN_SETUP;
722
723 capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
724 ap->nextMessageNumber++,
725 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
726 skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_ATOMIC);
727 if (!skb) {
728 dev_err(cs->dev, "%s: out of memory\n", __func__);
729 return;
730 }
731 capi_cmsg2message(&iif->hcmsg,
732 __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN));
733 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
734 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
735}
736
737/**
738 * gigaset_isdn_connD() - signal D channel connect
739 * @bcs: B channel descriptor structure.
740 *
741 * Called by main module at tasklet level to notify the LL that the D channel
742 * connection has been established.
743 */
744void gigaset_isdn_connD(struct bc_state *bcs)
745{
746 struct cardstate *cs = bcs->cs;
747 struct gigaset_capi_ctr *iif = cs->iif;
748 struct gigaset_capi_appl *ap = bcs->ap;
749 struct sk_buff *skb;
750 unsigned int msgsize;
751
752 if (!ap) {
753 dev_err(cs->dev, "%s: no application\n", __func__);
754 return;
755 }
756 while (ap->bcnext) {
757 /* this should never happen */
758 dev_warn(cs->dev, "%s: dropping extra application %u\n",
759 __func__, ap->bcnext->id);
760 send_disconnect_ind(bcs, ap->bcnext,
761 CapiCallGivenToOtherApplication);
762 ap->bcnext = ap->bcnext->bcnext;
763 }
764 if (ap->connected == APCONN_NONE) {
765 dev_warn(cs->dev, "%s: application %u not connected\n",
766 __func__, ap->id);
767 return;
768 }
769
770 /* prepare CONNECT_ACTIVE_IND message
771 * Note: LLC not supported by device
772 */
773 capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_CONNECT_ACTIVE, CAPI_IND,
774 ap->nextMessageNumber++,
775 iif->ctr.cnr | ((bcs->channel + 1) << 8));
776
777 /* minimum size, all structs empty */
778 msgsize = CAPI_CONNECT_ACTIVE_IND_BASELEN;
779
780 /* ToDo: set parameter: Connected number
781 * (requires ev-layer state machine extension to collect
782 * ZCON device reply)
783 */
784
785 /* build and emit CONNECT_ACTIVE_IND message */
786 skb = alloc_skb(msgsize, GFP_ATOMIC);
787 if (!skb) {
788 dev_err(cs->dev, "%s: out of memory\n", __func__);
789 return;
790 }
791 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
792 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
793 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
794}
795
796/**
797 * gigaset_isdn_hupD() - signal D channel hangup
798 * @bcs: B channel descriptor structure.
799 *
800 * Called by main module at tasklet level to notify the LL that the D channel
801 * connection has been shut down.
802 */
803void gigaset_isdn_hupD(struct bc_state *bcs)
804{
805 struct gigaset_capi_appl *ap;
806
807 /*
808 * ToDo: pass on reason code reported by device
809 * (requires ev-layer state machine extension to collect
810 * ZCAU device reply)
811 */
812 for (ap = bcs->ap; ap != NULL; ap = ap->bcnext) {
813 send_disconnect_b3_ind(bcs, ap);
814 send_disconnect_ind(bcs, ap, 0);
815 }
816 bcs->ap = NULL;
817}
818
819/**
820 * gigaset_isdn_connB() - signal B channel connect
821 * @bcs: B channel descriptor structure.
822 *
823 * Called by main module at tasklet level to notify the LL that the B channel
824 * connection has been established.
825 */
826void gigaset_isdn_connB(struct bc_state *bcs)
827{
828 struct cardstate *cs = bcs->cs;
829 struct gigaset_capi_ctr *iif = cs->iif;
830 struct gigaset_capi_appl *ap = bcs->ap;
831 struct sk_buff *skb;
832 unsigned int msgsize;
833 u8 command;
834
835 if (!ap) {
836 dev_err(cs->dev, "%s: no application\n", __func__);
837 return;
838 }
839 while (ap->bcnext) {
840 /* this should never happen */
841 dev_warn(cs->dev, "%s: dropping extra application %u\n",
842 __func__, ap->bcnext->id);
843 send_disconnect_ind(bcs, ap->bcnext,
844 CapiCallGivenToOtherApplication);
845 ap->bcnext = ap->bcnext->bcnext;
846 }
847 if (!ap->connected) {
848 dev_warn(cs->dev, "%s: application %u not connected\n",
849 __func__, ap->id);
850 return;
851 }
852
853 /*
854 * emit CONNECT_B3_ACTIVE_IND if we already got CONNECT_B3_REQ;
855 * otherwise we have to emit CONNECT_B3_IND first, and follow up with
856 * CONNECT_B3_ACTIVE_IND in reply to CONNECT_B3_RESP
857 * Parameters in both cases always: NCCI = 1, NCPI empty
858 */
859 if (ap->connected >= APCONN_ACTIVE) {
860 command = CAPI_CONNECT_B3_ACTIVE;
861 msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
862 } else {
863 command = CAPI_CONNECT_B3;
864 msgsize = CAPI_CONNECT_B3_IND_BASELEN;
865 }
866 capi_cmsg_header(&iif->hcmsg, ap->id, command, CAPI_IND,
867 ap->nextMessageNumber++,
868 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
869 skb = alloc_skb(msgsize, GFP_ATOMIC);
870 if (!skb) {
871 dev_err(cs->dev, "%s: out of memory\n", __func__);
872 return;
873 }
874 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
875 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
876 ap->connected = APCONN_ACTIVE;
877 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
878}
879
880/**
881 * gigaset_isdn_hupB() - signal B channel hangup
882 * @bcs: B channel descriptor structure.
883 *
884 * Called by main module to notify the LL that the B channel connection has
885 * been shut down.
886 */
887void gigaset_isdn_hupB(struct bc_state *bcs)
888{
889 struct cardstate *cs = bcs->cs;
890 struct gigaset_capi_appl *ap = bcs->ap;
891
892 /* ToDo: assure order of DISCONNECT_B3_IND and DISCONNECT_IND ? */
893
894 if (!ap) {
895 dev_err(cs->dev, "%s: no application\n", __func__);
896 return;
897 }
898
899 send_disconnect_b3_ind(bcs, ap);
900}
901
902/**
903 * gigaset_isdn_start() - signal device availability
904 * @cs: device descriptor structure.
905 *
906 * Called by main module to notify the LL that the device is available for
907 * use.
908 */
909void gigaset_isdn_start(struct cardstate *cs)
910{
911 struct gigaset_capi_ctr *iif = cs->iif;
912
913 /* fill profile data: manufacturer name */
914 strcpy(iif->ctr.manu, "Siemens");
915 /* CAPI and device version */
916 iif->ctr.version.majorversion = 2; /* CAPI 2.0 */
917 iif->ctr.version.minorversion = 0;
918 /* ToDo: check/assert cs->gotfwver? */
919 iif->ctr.version.majormanuversion = cs->fwver[0];
920 iif->ctr.version.minormanuversion = cs->fwver[1];
921 /* number of B channels supported */
922 iif->ctr.profile.nbchannel = cs->channels;
923 /* global options: internal controller, supplementary services */
924 iif->ctr.profile.goptions = 0x11;
925 /* B1 protocols: 64 kbit/s HDLC or transparent */
926 iif->ctr.profile.support1 = 0x03;
927 /* B2 protocols: transparent only */
928 /* ToDo: X.75 SLP ? */
929 iif->ctr.profile.support2 = 0x02;
930 /* B3 protocols: transparent only */
931 iif->ctr.profile.support3 = 0x01;
932 /* no serial number */
933 strcpy(iif->ctr.serial, "0");
934 capi_ctr_ready(&iif->ctr);
935}
936
937/**
938 * gigaset_isdn_stop() - signal device unavailability
939 * @cs: device descriptor structure.
940 *
941 * Called by main module to notify the LL that the device is no longer
942 * available for use.
943 */
944void gigaset_isdn_stop(struct cardstate *cs)
945{
946 struct gigaset_capi_ctr *iif = cs->iif;
947 capi_ctr_down(&iif->ctr);
948}
949
950/*
951 * kernel CAPI callback methods
952 * ============================
953 */
954
955/*
956 * load firmware
957 */
958static int gigaset_load_firmware(struct capi_ctr *ctr, capiloaddata *data)
959{
960 struct cardstate *cs = ctr->driverdata;
961
962 /* AVM specific operation, not needed for Gigaset -- ignore */
963 dev_notice(cs->dev, "load_firmware ignored\n");
964
965 return 0;
966}
967
968/*
969 * reset (deactivate) controller
970 */
971static void gigaset_reset_ctr(struct capi_ctr *ctr)
972{
973 struct cardstate *cs = ctr->driverdata;
974
975 /* AVM specific operation, not needed for Gigaset -- ignore */
976 dev_notice(cs->dev, "reset_ctr ignored\n");
977}
978
979/*
980 * register CAPI application
981 */
982static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
983 capi_register_params *rp)
984{
985 struct gigaset_capi_ctr *iif
986 = container_of(ctr, struct gigaset_capi_ctr, ctr);
987 struct cardstate *cs = ctr->driverdata;
988 struct gigaset_capi_appl *ap;
989
990 list_for_each_entry(ap, &iif->appls, ctrlist)
991 if (ap->id == appl) {
992 dev_notice(cs->dev,
993 "application %u already registered\n", appl);
994 return;
995 }
996
997 ap = kzalloc(sizeof(*ap), GFP_KERNEL);
998 if (!ap) {
999 dev_err(cs->dev, "%s: out of memory\n", __func__);
1000 return;
1001 }
1002 ap->id = appl;
1003
1004 list_add(&ap->ctrlist, &iif->appls);
1005}
1006
1007/*
1008 * release CAPI application
1009 */
1010static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
1011{
1012 struct gigaset_capi_ctr *iif
1013 = container_of(ctr, struct gigaset_capi_ctr, ctr);
1014 struct cardstate *cs = iif->ctr.driverdata;
1015 struct gigaset_capi_appl *ap, *tmp;
1016
1017 list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
1018 if (ap->id == appl) {
1019 if (ap->connected != APCONN_NONE) {
1020 dev_err(cs->dev,
1021 "%s: application %u still connected\n",
1022 __func__, ap->id);
1023 /* ToDo: clear active connection */
1024 }
1025 list_del(&ap->ctrlist);
1026 kfree(ap);
1027 }
1028
1029}
1030
1031/*
1032 * =====================================================================
1033 * outgoing CAPI message handler
1034 * =====================================================================
1035 */
1036
1037/*
1038 * helper function: emit reply message with given Info value
1039 */
1040static void send_conf(struct gigaset_capi_ctr *iif,
1041 struct gigaset_capi_appl *ap,
1042 struct sk_buff *skb,
1043 u16 info)
1044{
1045 /*
1046 * _CONF replies always only have NCCI and Info parameters
1047 * so they'll fit into the _REQ message skb
1048 */
1049 capi_cmsg_answer(&iif->acmsg);
1050 iif->acmsg.Info = info;
1051 capi_cmsg2message(&iif->acmsg, skb->data);
1052 __skb_trim(skb, CAPI_STDCONF_LEN);
1053 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1054 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
1055}
1056
1057/*
1058 * process FACILITY_REQ message
1059 */
1060static void do_facility_req(struct gigaset_capi_ctr *iif,
1061 struct gigaset_capi_appl *ap,
1062 struct sk_buff *skb)
1063{
1064 struct cardstate *cs = iif->ctr.driverdata;
1065 struct sk_buff *cskb;
1066 u8 *pparam;
1067 unsigned int msgsize = CAPI_FACILITY_CONF_BASELEN;
1068 u16 function, info;
1069 static u8 confparam[10]; /* max. 9 octets + length byte */
1070
1071 /* decode message */
1072 capi_message2cmsg(&iif->acmsg, skb->data);
1073 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1074
1075 /*
1076 * Facility Request Parameter is not decoded by capi_message2cmsg()
1077 * encoding depends on Facility Selector
1078 */
1079 switch (iif->acmsg.FacilitySelector) {
1080 case CAPI_FACILITY_DTMF: /* ToDo */
1081 info = CapiFacilityNotSupported;
1082 confparam[0] = 2; /* length */
1083 /* DTMF information: Unknown DTMF request */
1084 capimsg_setu16(confparam, 1, 2);
1085 break;
1086
1087 case CAPI_FACILITY_V42BIS: /* not supported */
1088 info = CapiFacilityNotSupported;
1089 confparam[0] = 2; /* length */
1090 /* V.42 bis information: not available */
1091 capimsg_setu16(confparam, 1, 1);
1092 break;
1093
1094 case CAPI_FACILITY_SUPPSVC:
1095 /* decode Function parameter */
1096 pparam = iif->acmsg.FacilityRequestParameter;
1097 if (pparam == NULL || *pparam < 2) {
1098 dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
1099 "Facility Request Parameter");
1100 send_conf(iif, ap, skb, CapiIllMessageParmCoding);
1101 return;
1102 }
1103 function = CAPIMSG_U16(pparam, 1);
1104 switch (function) {
1105 case CAPI_SUPPSVC_GETSUPPORTED:
1106 info = CapiSuccess;
1107 /* Supplementary Service specific parameter */
1108 confparam[3] = 6; /* length */
1109 /* Supplementary services info: Success */
1110 capimsg_setu16(confparam, 4, CapiSuccess);
1111 /* Supported Services: none */
1112 capimsg_setu32(confparam, 6, 0);
1113 break;
1114 /* ToDo: add supported services */
1115 default:
1116 info = CapiFacilitySpecificFunctionNotSupported;
1117 /* Supplementary Service specific parameter */
1118 confparam[3] = 2; /* length */
1119 /* Supplementary services info: not supported */
1120 capimsg_setu16(confparam, 4,
1121 CapiSupplementaryServiceNotSupported);
1122 }
1123
1124 /* Facility confirmation parameter */
1125 confparam[0] = confparam[3] + 3; /* total length */
1126 /* Function: copy from _REQ message */
1127 capimsg_setu16(confparam, 1, function);
1128 /* Supplementary Service specific parameter already set above */
1129 break;
1130
1131 case CAPI_FACILITY_WAKEUP: /* ToDo */
1132 info = CapiFacilityNotSupported;
1133 confparam[0] = 2; /* length */
1134 /* Number of accepted awake request parameters: 0 */
1135 capimsg_setu16(confparam, 1, 0);
1136 break;
1137
1138 default:
1139 info = CapiFacilityNotSupported;
1140 confparam[0] = 0; /* empty struct */
1141 }
1142
1143 /* send FACILITY_CONF with given Info and confirmation parameter */
1144 capi_cmsg_answer(&iif->acmsg);
1145 iif->acmsg.Info = info;
1146 iif->acmsg.FacilityConfirmationParameter = confparam;
1147 msgsize += confparam[0]; /* length */
1148 cskb = alloc_skb(msgsize, GFP_ATOMIC);
1149 if (!cskb) {
1150 dev_err(cs->dev, "%s: out of memory\n", __func__);
1151 return;
1152 }
1153 capi_cmsg2message(&iif->acmsg, __skb_put(cskb, msgsize));
1154 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1155 capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
1156}
1157
1158
1159/*
1160 * process LISTEN_REQ message
1161 * just store the masks in the application data structure
1162 */
1163static void do_listen_req(struct gigaset_capi_ctr *iif,
1164 struct gigaset_capi_appl *ap,
1165 struct sk_buff *skb)
1166{
1167 /* decode message */
1168 capi_message2cmsg(&iif->acmsg, skb->data);
1169 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1170
1171 /* store listening parameters */
1172 ap->listenInfoMask = iif->acmsg.InfoMask;
1173 ap->listenCIPmask = iif->acmsg.CIPmask;
1174 send_conf(iif, ap, skb, CapiSuccess);
1175}
1176
1177/*
1178 * process ALERT_REQ message
1179 * nothing to do, Gigaset always alerts anyway
1180 */
1181static void do_alert_req(struct gigaset_capi_ctr *iif,
1182 struct gigaset_capi_appl *ap,
1183 struct sk_buff *skb)
1184{
1185 /* decode message */
1186 capi_message2cmsg(&iif->acmsg, skb->data);
1187 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1188 send_conf(iif, ap, skb, CapiAlertAlreadySent);
1189}
1190
1191/*
1192 * process CONNECT_REQ message
1193 * allocate a B channel, prepare dial commands, queue a DIAL event,
1194 * emit CONNECT_CONF reply
1195 */
1196static void do_connect_req(struct gigaset_capi_ctr *iif,
1197 struct gigaset_capi_appl *ap,
1198 struct sk_buff *skb)
1199{
1200 struct cardstate *cs = iif->ctr.driverdata;
1201 _cmsg *cmsg = &iif->acmsg;
1202 struct bc_state *bcs;
1203 char **commands;
1204 char *s;
1205 u8 *pp;
1206 int i, l;
1207 u16 info;
1208
1209 /* decode message */
1210 capi_message2cmsg(&iif->acmsg, skb->data);
1211 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1212
1213 /* get free B channel & construct PLCI */
1214 bcs = gigaset_get_free_channel(cs);
1215 if (!bcs) {
1216 dev_notice(cs->dev, "%s: no B channel available\n",
1217 "CONNECT_REQ");
1218 send_conf(iif, ap, skb, CapiNoPlciAvailable);
1219 return;
1220 }
1221 ap->bcnext = NULL;
1222 bcs->ap = ap;
1223 cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;
1224
1225 /* build command table */
1226 commands = kzalloc(AT_NUM*(sizeof *commands), GFP_KERNEL);
1227 if (!commands)
1228 goto oom;
1229
1230 /* encode parameter: Called party number */
1231 pp = cmsg->CalledPartyNumber;
1232 if (pp == NULL || *pp == 0) {
1233 dev_notice(cs->dev, "%s: %s missing\n",
1234 "CONNECT_REQ", "Called party number");
1235 info = CapiIllMessageParmCoding;
1236 goto error;
1237 }
1238 l = *pp++;
1239 /* check type of number/numbering plan byte */
1240 switch (*pp) {
1241 case 0x80: /* unknown type / unknown numbering plan */
1242 case 0x81: /* unknown type / ISDN/Telephony numbering plan */
1243 break;
1244 default: /* others: warn about potential misinterpretation */
1245 dev_notice(cs->dev, "%s: %s type/plan 0x%02x unsupported\n",
1246 "CONNECT_REQ", "Called party number", *pp);
1247 }
1248 pp++;
1249 l--;
1250 /* translate "**" internal call prefix to CTP value */
1251 if (l >= 2 && pp[0] == '*' && pp[1] == '*') {
1252 s = "^SCTP=0\r";
1253 pp += 2;
1254 l -= 2;
1255 } else {
1256 s = "^SCTP=1\r";
1257 }
1258 commands[AT_TYPE] = kstrdup(s, GFP_KERNEL);
1259 if (!commands[AT_TYPE])
1260 goto oom;
1261 commands[AT_DIAL] = kmalloc(l+3, GFP_KERNEL);
1262 if (!commands[AT_DIAL])
1263 goto oom;
1264 snprintf(commands[AT_DIAL], l+3, "D%*s\r", l, pp);
1265
1266 /* encode parameter: Calling party number */
1267 pp = cmsg->CallingPartyNumber;
1268 if (pp != NULL && *pp > 0) {
1269 l = *pp++;
1270
1271 /* check type of number/numbering plan byte */
1272 /* ToDo: allow for/handle Ext=1? */
1273 switch (*pp) {
1274 case 0x00: /* unknown type / unknown numbering plan */
1275 case 0x01: /* unknown type / ISDN/Telephony num. plan */
1276 break;
1277 default:
1278 dev_notice(cs->dev,
1279 "%s: %s type/plan 0x%02x unsupported\n",
1280 "CONNECT_REQ", "Calling party number", *pp);
1281 }
1282 pp++;
1283 l--;
1284
1285 /* check presentation indicator */
1286 if (!l) {
1287 dev_notice(cs->dev, "%s: %s IE truncated\n",
1288 "CONNECT_REQ", "Calling party number");
1289 info = CapiIllMessageParmCoding;
1290 goto error;
1291 }
1292 switch (*pp & 0xfc) { /* ignore Screening indicator */
1293 case 0x80: /* Presentation allowed */
1294 s = "^SCLIP=1\r";
1295 break;
1296 case 0xa0: /* Presentation restricted */
1297 s = "^SCLIP=0\r";
1298 break;
1299 default:
1300 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1301 "CONNECT_REQ",
1302 "Presentation/Screening indicator",
1303 *pp);
1304 s = "^SCLIP=1\r";
1305 }
1306 commands[AT_CLIP] = kstrdup(s, GFP_KERNEL);
1307 if (!commands[AT_CLIP])
1308 goto oom;
1309 pp++;
1310 l--;
1311
1312 if (l) {
1313 /* number */
1314 commands[AT_MSN] = kmalloc(l+8, GFP_KERNEL);
1315 if (!commands[AT_MSN])
1316 goto oom;
1317 snprintf(commands[AT_MSN], l+8, "^SMSN=%*s\r", l, pp);
1318 }
1319 }
1320
1321 /* check parameter: CIP Value */
1322 if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) ||
1323 (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
1324 dev_notice(cs->dev, "%s: unknown CIP value %d\n",
1325 "CONNECT_REQ", cmsg->CIPValue);
1326 info = CapiCipValueUnknown;
1327 goto error;
1328 }
1329
1330 /* check/encode parameter: BC */
1331 if (cmsg->BC && cmsg->BC[0]) {
1332 /* explicit BC overrides CIP */
1333 l = 2*cmsg->BC[0] + 7;
1334 commands[AT_BC] = kmalloc(l, GFP_KERNEL);
1335 if (!commands[AT_BC])
1336 goto oom;
1337 strcpy(commands[AT_BC], "^SBC=");
1338 decode_ie(cmsg->BC, commands[AT_BC]+5);
1339 strcpy(commands[AT_BC] + l - 2, "\r");
1340 } else if (cip2bchlc[cmsg->CIPValue].bc) {
1341 l = strlen(cip2bchlc[cmsg->CIPValue].bc) + 7;
1342 commands[AT_BC] = kmalloc(l, GFP_KERNEL);
1343 if (!commands[AT_BC])
1344 goto oom;
1345 snprintf(commands[AT_BC], l, "^SBC=%s\r",
1346 cip2bchlc[cmsg->CIPValue].bc);
1347 }
1348
1349 /* check/encode parameter: HLC */
1350 if (cmsg->HLC && cmsg->HLC[0]) {
1351 /* explicit HLC overrides CIP */
1352 l = 2*cmsg->HLC[0] + 7;
1353 commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
1354 if (!commands[AT_HLC])
1355 goto oom;
1356 strcpy(commands[AT_HLC], "^SHLC=");
1357 decode_ie(cmsg->HLC, commands[AT_HLC]+5);
1358 strcpy(commands[AT_HLC] + l - 2, "\r");
1359 } else if (cip2bchlc[cmsg->CIPValue].hlc) {
1360 l = strlen(cip2bchlc[cmsg->CIPValue].hlc) + 7;
1361 commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
1362 if (!commands[AT_HLC])
1363 goto oom;
1364 snprintf(commands[AT_HLC], l, "^SHLC=%s\r",
1365 cip2bchlc[cmsg->CIPValue].hlc);
1366 }
1367
1368 /* check/encode parameter: B Protocol */
1369 if (cmsg->BProtocol == CAPI_DEFAULT) {
1370 bcs->proto2 = L2_HDLC;
1371 dev_warn(cs->dev,
1372 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
1373 } else {
1374 switch (cmsg->B1protocol) {
1375 case 0:
1376 bcs->proto2 = L2_HDLC;
1377 break;
1378 case 1:
1379 bcs->proto2 = L2_BITSYNC;
1380 break;
1381 default:
1382 dev_warn(cs->dev,
1383 "B1 Protocol %u unsupported, using Transparent\n",
1384 cmsg->B1protocol);
1385 bcs->proto2 = L2_BITSYNC;
1386 }
1387 if (cmsg->B2protocol != 1)
1388 dev_warn(cs->dev,
1389 "B2 Protocol %u unsupported, using Transparent\n",
1390 cmsg->B2protocol);
1391 if (cmsg->B3protocol != 0)
1392 dev_warn(cs->dev,
1393 "B3 Protocol %u unsupported, using Transparent\n",
1394 cmsg->B3protocol);
1395 ignore_cstruct_param(cs, cmsg->B1configuration,
1396 "CONNECT_REQ", "B1 Configuration");
1397 ignore_cstruct_param(cs, cmsg->B2configuration,
1398 "CONNECT_REQ", "B2 Configuration");
1399 ignore_cstruct_param(cs, cmsg->B3configuration,
1400 "CONNECT_REQ", "B3 Configuration");
1401 }
1402 commands[AT_PROTO] = kmalloc(9, GFP_KERNEL);
1403 if (!commands[AT_PROTO])
1404 goto oom;
1405 snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
1406
1407 /* ToDo: check/encode remaining parameters */
1408 ignore_cstruct_param(cs, cmsg->CalledPartySubaddress,
1409 "CONNECT_REQ", "Called pty subaddr");
1410 ignore_cstruct_param(cs, cmsg->CallingPartySubaddress,
1411 "CONNECT_REQ", "Calling pty subaddr");
1412 ignore_cstruct_param(cs, cmsg->LLC,
1413 "CONNECT_REQ", "LLC");
1414 ignore_cmstruct_param(cs, cmsg->AdditionalInfo,
1415 "CONNECT_REQ", "Additional Info");
1416
1417 /* encode parameter: B channel to use */
1418 commands[AT_ISO] = kmalloc(9, GFP_KERNEL);
1419 if (!commands[AT_ISO])
1420 goto oom;
1421 snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
1422 (unsigned) bcs->channel + 1);
1423
1424 /* queue & schedule EV_DIAL event */
1425 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
1426 bcs->at_state.seq_index, NULL))
1427 goto oom;
1428 gig_dbg(DEBUG_CMD, "scheduling DIAL");
1429 gigaset_schedule_event(cs);
1430 ap->connected = APCONN_SETUP;
1431 send_conf(iif, ap, skb, CapiSuccess);
1432 return;
1433
1434oom:
1435 dev_err(cs->dev, "%s: out of memory\n", __func__);
1436 info = CAPI_MSGOSRESOURCEERR;
1437error:
1438 if (commands)
1439 for (i = 0; i < AT_NUM; i++)
1440 kfree(commands[i]);
1441 kfree(commands);
1442 gigaset_free_channel(bcs);
1443 send_conf(iif, ap, skb, info);
1444}
1445
1446/*
1447 * process CONNECT_RESP message
1448 * checks protocol parameters and queues an ACCEPT or HUP event
1449 */
1450static void do_connect_resp(struct gigaset_capi_ctr *iif,
1451 struct gigaset_capi_appl *ap,
1452 struct sk_buff *skb)
1453{
1454 struct cardstate *cs = iif->ctr.driverdata;
1455 _cmsg *cmsg = &iif->acmsg;
1456 struct bc_state *bcs;
1457 struct gigaset_capi_appl *oap;
1458 int channel;
1459
1460 /* decode message */
1461 capi_message2cmsg(&iif->acmsg, skb->data);
1462 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1463 dev_kfree_skb(skb);
1464
1465 /* extract and check channel number from PLCI */
1466 channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
1467 if (!channel || channel > cs->channels) {
1468 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1469 "CONNECT_RESP", "PLCI", cmsg->adr.adrPLCI);
1470 return;
1471 }
1472 bcs = cs->bcs + channel - 1;
1473
1474 switch (cmsg->Reject) {
1475 case 0: /* Accept */
1476 /* drop all competing applications, keep only this one */
1477 for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
1478 if (oap != ap)
1479 send_disconnect_ind(bcs, oap,
1480 CapiCallGivenToOtherApplication);
1481 ap->bcnext = NULL;
1482 bcs->ap = ap;
1483 bcs->chstate |= CHS_NOTIFY_LL;
1484
1485 /* check/encode B channel protocol */
1486 if (cmsg->BProtocol == CAPI_DEFAULT) {
1487 bcs->proto2 = L2_HDLC;
1488 dev_warn(cs->dev,
1489 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
1490 } else {
1491 switch (cmsg->B1protocol) {
1492 case 0:
1493 bcs->proto2 = L2_HDLC;
1494 break;
1495 case 1:
1496 bcs->proto2 = L2_BITSYNC;
1497 break;
1498 default:
1499 dev_warn(cs->dev,
1500 "B1 Protocol %u unsupported, using Transparent\n",
1501 cmsg->B1protocol);
1502 bcs->proto2 = L2_BITSYNC;
1503 }
1504 if (cmsg->B2protocol != 1)
1505 dev_warn(cs->dev,
1506 "B2 Protocol %u unsupported, using Transparent\n",
1507 cmsg->B2protocol);
1508 if (cmsg->B3protocol != 0)
1509 dev_warn(cs->dev,
1510 "B3 Protocol %u unsupported, using Transparent\n",
1511 cmsg->B3protocol);
1512 ignore_cstruct_param(cs, cmsg->B1configuration,
1513 "CONNECT_RESP", "B1 Configuration");
1514 ignore_cstruct_param(cs, cmsg->B2configuration,
1515 "CONNECT_RESP", "B2 Configuration");
1516 ignore_cstruct_param(cs, cmsg->B3configuration,
1517 "CONNECT_RESP", "B3 Configuration");
1518 }
1519
1520 /* ToDo: check/encode remaining parameters */
1521 ignore_cstruct_param(cs, cmsg->ConnectedNumber,
1522 "CONNECT_RESP", "Connected Number");
1523 ignore_cstruct_param(cs, cmsg->ConnectedSubaddress,
1524 "CONNECT_RESP", "Connected Subaddress");
1525 ignore_cstruct_param(cs, cmsg->LLC,
1526 "CONNECT_RESP", "LLC");
1527 ignore_cmstruct_param(cs, cmsg->AdditionalInfo,
1528 "CONNECT_RESP", "Additional Info");
1529
1530 /* Accept call */
1531 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1532 EV_ACCEPT, NULL, 0, NULL))
1533 return;
1534 gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
1535 gigaset_schedule_event(cs);
1536 return;
1537
1538 case 1: /* Ignore */
1539 /* send DISCONNECT_IND to this application */
1540 send_disconnect_ind(bcs, ap, 0);
1541
1542 /* remove it from the list of listening apps */
1543 if (bcs->ap == ap) {
1544 bcs->ap = ap->bcnext;
1545 if (bcs->ap == NULL)
1546 /* last one: stop ev-layer hupD notifications */
1547 bcs->chstate &= ~CHS_NOTIFY_LL;
1548 return;
1549 }
1550 for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) {
1551 if (oap->bcnext == ap) {
1552 oap->bcnext = oap->bcnext->bcnext;
1553 return;
1554 }
1555 }
1556 dev_err(cs->dev, "%s: application %u not found\n",
1557 __func__, ap->id);
1558 return;
1559
1560 default: /* Reject */
1561 /* drop all competing applications, keep only this one */
1562 for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
1563 if (oap != ap)
1564 send_disconnect_ind(bcs, oap,
1565 CapiCallGivenToOtherApplication);
1566 ap->bcnext = NULL;
1567 bcs->ap = ap;
1568
1569 /* reject call - will trigger DISCONNECT_IND for this app */
1570 dev_info(cs->dev, "%s: Reject=%x\n",
1571 "CONNECT_RESP", cmsg->Reject);
1572 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1573 EV_HUP, NULL, 0, NULL))
1574 return;
1575 gig_dbg(DEBUG_CMD, "scheduling HUP");
1576 gigaset_schedule_event(cs);
1577 return;
1578 }
1579}
1580
1581/*
1582 * process CONNECT_B3_REQ message
1583 * build NCCI and emit CONNECT_B3_CONF reply
1584 */
1585static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
1586 struct gigaset_capi_appl *ap,
1587 struct sk_buff *skb)
1588{
1589 struct cardstate *cs = iif->ctr.driverdata;
1590 int channel;
1591
1592 /* decode message */
1593 capi_message2cmsg(&iif->acmsg, skb->data);
1594 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1595
1596 /* extract and check channel number from PLCI */
1597 channel = (iif->acmsg.adr.adrPLCI >> 8) & 0xff;
1598 if (!channel || channel > cs->channels) {
1599 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1600 "CONNECT_B3_REQ", "PLCI", iif->acmsg.adr.adrPLCI);
1601 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1602 return;
1603 }
1604
1605 /* mark logical connection active */
1606 ap->connected = APCONN_ACTIVE;
1607
1608 /* build NCCI: always 1 (one B3 connection only) */
1609 iif->acmsg.adr.adrNCCI |= 1 << 16;
1610
1611 /* NCPI parameter: not applicable for B3 Transparent */
1612 ignore_cstruct_param(cs, iif->acmsg.NCPI,
1613 "CONNECT_B3_REQ", "NCPI");
1614 send_conf(iif, ap, skb,
1615 (iif->acmsg.NCPI && iif->acmsg.NCPI[0]) ?
1616 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1617}
1618
1619/*
1620 * process CONNECT_B3_RESP message
1621 * Depending on the Reject parameter, either emit CONNECT_B3_ACTIVE_IND
1622 * or queue EV_HUP and emit DISCONNECT_B3_IND.
1623 * The emitted message is always shorter than the received one,
1624 * allowing to reuse the skb.
1625 */
1626static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
1627 struct gigaset_capi_appl *ap,
1628 struct sk_buff *skb)
1629{
1630 struct cardstate *cs = iif->ctr.driverdata;
1631 struct bc_state *bcs = NULL;
1632 int channel;
1633 unsigned int msgsize;
1634 u8 command;
1635
1636 /* decode message */
1637 capi_message2cmsg(&iif->acmsg, skb->data);
1638 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1639
1640 /* extract and check channel number and NCCI */
1641 channel = (iif->acmsg.adr.adrNCCI >> 8) & 0xff;
1642 if (!channel || channel > cs->channels ||
1643 ((iif->acmsg.adr.adrNCCI >> 16) & 0xffff) != 1) {
1644 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1645 "CONNECT_B3_RESP", "NCCI", iif->acmsg.adr.adrNCCI);
1646 dev_kfree_skb(skb);
1647 return;
1648 }
1649 bcs = &cs->bcs[channel-1];
1650
1651 if (iif->acmsg.Reject) {
1652 /* Reject: clear B3 connect received flag */
1653 ap->connected = APCONN_SETUP;
1654
1655 /* trigger hangup, causing eventual DISCONNECT_IND */
1656 if (!gigaset_add_event(cs, &bcs->at_state,
1657 EV_HUP, NULL, 0, NULL)) {
1658 dev_err(cs->dev, "%s: out of memory\n", __func__);
1659 dev_kfree_skb(skb);
1660 return;
1661 }
1662 gig_dbg(DEBUG_CMD, "scheduling HUP");
1663 gigaset_schedule_event(cs);
1664
1665 /* emit DISCONNECT_B3_IND */
1666 command = CAPI_DISCONNECT_B3;
1667 msgsize = CAPI_DISCONNECT_B3_IND_BASELEN;
1668 } else {
1669 /*
1670 * Accept: emit CONNECT_B3_ACTIVE_IND immediately, as
1671 * we only send CONNECT_B3_IND if the B channel is up
1672 */
1673 command = CAPI_CONNECT_B3_ACTIVE;
1674 msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
1675 }
1676 capi_cmsg_header(&iif->acmsg, ap->id, command, CAPI_IND,
1677 ap->nextMessageNumber++, iif->acmsg.adr.adrNCCI);
1678 __skb_trim(skb, msgsize);
1679 capi_cmsg2message(&iif->acmsg, skb->data);
1680 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1681 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
1682}
1683
1684/*
1685 * process DISCONNECT_REQ message
1686 * schedule EV_HUP and emit DISCONNECT_B3_IND if necessary,
1687 * emit DISCONNECT_CONF reply
1688 */
1689static void do_disconnect_req(struct gigaset_capi_ctr *iif,
1690 struct gigaset_capi_appl *ap,
1691 struct sk_buff *skb)
1692{
1693 struct cardstate *cs = iif->ctr.driverdata;
1694 struct bc_state *bcs;
1695 _cmsg *b3cmsg;
1696 struct sk_buff *b3skb;
1697 int channel;
1698
1699 /* decode message */
1700 capi_message2cmsg(&iif->acmsg, skb->data);
1701 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1702
1703 /* extract and check channel number from PLCI */
1704 channel = (iif->acmsg.adr.adrPLCI >> 8) & 0xff;
1705 if (!channel || channel > cs->channels) {
1706 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1707 "DISCONNECT_REQ", "PLCI", iif->acmsg.adr.adrPLCI);
1708 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1709 return;
1710 }
1711 bcs = cs->bcs + channel - 1;
1712
1713 /* ToDo: process parameter: Additional info */
1714 ignore_cmstruct_param(cs, iif->acmsg.AdditionalInfo,
1715 "DISCONNECT_REQ", "Additional Info");
1716
1717 /* skip if DISCONNECT_IND already sent */
1718 if (!ap->connected)
1719 return;
1720
1721 /* check for active logical connection */
1722 if (ap->connected >= APCONN_ACTIVE) {
1723 /*
1724 * emit DISCONNECT_B3_IND with cause 0x3301
1725 * use separate cmsg structure, as the content of iif->acmsg
1726 * is still needed for creating the _CONF message
1727 */
1728 b3cmsg = kmalloc(sizeof(*b3cmsg), GFP_KERNEL);
1729 if (!b3cmsg) {
1730 dev_err(cs->dev, "%s: out of memory\n", __func__);
1731 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1732 return;
1733 }
1734 capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
1735 ap->nextMessageNumber++,
1736 iif->acmsg.adr.adrPLCI | (1 << 16));
1737 b3cmsg->Reason_B3 = CapiProtocolErrorLayer1;
1738 b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL);
1739 if (b3skb == NULL) {
1740 dev_err(cs->dev, "%s: out of memory\n", __func__);
1741 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1742 return;
1743 }
1744 capi_cmsg2message(b3cmsg,
1745 __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
1746 kfree(b3cmsg);
1747 capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
1748 }
1749
1750 /* trigger hangup, causing eventual DISCONNECT_IND */
1751 if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
1752 dev_err(cs->dev, "%s: out of memory\n", __func__);
1753 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1754 return;
1755 }
1756 gig_dbg(DEBUG_CMD, "scheduling HUP");
1757 gigaset_schedule_event(cs);
1758
1759 /* emit reply */
1760 send_conf(iif, ap, skb, CapiSuccess);
1761}
1762
1763/*
1764 * process DISCONNECT_B3_REQ message
1765 * schedule EV_HUP and emit DISCONNECT_B3_CONF reply
1766 */
1767static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
1768 struct gigaset_capi_appl *ap,
1769 struct sk_buff *skb)
1770{
1771 struct cardstate *cs = iif->ctr.driverdata;
1772 int channel;
1773
1774 /* decode message */
1775 capi_message2cmsg(&iif->acmsg, skb->data);
1776 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1777
1778 /* extract and check channel number and NCCI */
1779 channel = (iif->acmsg.adr.adrNCCI >> 8) & 0xff;
1780 if (!channel || channel > cs->channels ||
1781 ((iif->acmsg.adr.adrNCCI >> 16) & 0xffff) != 1) {
1782 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1783 "DISCONNECT_B3_REQ", "NCCI", iif->acmsg.adr.adrNCCI);
1784 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1785 return;
1786 }
1787
1788 /* reject if logical connection not active */
1789 if (ap->connected < APCONN_ACTIVE) {
1790 send_conf(iif, ap, skb,
1791 CapiMessageNotSupportedInCurrentState);
1792 return;
1793 }
1794
1795 /* trigger hangup, causing eventual DISCONNECT_B3_IND */
1796 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1797 EV_HUP, NULL, 0, NULL)) {
1798 dev_err(cs->dev, "%s: out of memory\n", __func__);
1799 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1800 return;
1801 }
1802 gig_dbg(DEBUG_CMD, "scheduling HUP");
1803 gigaset_schedule_event(cs);
1804
1805 /* NCPI parameter: not applicable for B3 Transparent */
1806 ignore_cstruct_param(cs, iif->acmsg.NCPI,
1807 "DISCONNECT_B3_REQ", "NCPI");
1808 send_conf(iif, ap, skb,
1809 (iif->acmsg.NCPI && iif->acmsg.NCPI[0]) ?
1810 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1811}
1812
1813/*
1814 * process DATA_B3_REQ message
1815 */
1816static void do_data_b3_req(struct gigaset_capi_ctr *iif,
1817 struct gigaset_capi_appl *ap,
1818 struct sk_buff *skb)
1819{
1820 struct cardstate *cs = iif->ctr.driverdata;
1821 int channel = CAPIMSG_PLCI_PART(skb->data);
1822 u16 ncci = CAPIMSG_NCCI_PART(skb->data);
1823 u16 msglen = CAPIMSG_LEN(skb->data);
1824 u16 datalen = CAPIMSG_DATALEN(skb->data);
1825 u16 flags = CAPIMSG_FLAGS(skb->data);
1826
1827 /* frequent message, avoid _cmsg overhead */
1828 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);
1829
1830 gig_dbg(DEBUG_LLDATA,
1831 "Receiving data from LL (ch: %d, flg: %x, sz: %d|%d)",
1832 channel, flags, msglen, datalen);
1833
1834 /* check parameters */
1835 if (channel == 0 || channel > cs->channels || ncci != 1) {
1836 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1837 "DATA_B3_REQ", "NCCI", CAPIMSG_NCCI(skb->data));
1838 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1839 return;
1840 }
1841 if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
1842 dev_notice(cs->dev, "%s: unexpected length %d\n",
1843 "DATA_B3_REQ", msglen);
1844 if (msglen + datalen != skb->len)
1845 dev_notice(cs->dev, "%s: length mismatch (%d+%d!=%d)\n",
1846 "DATA_B3_REQ", msglen, datalen, skb->len);
1847 if (msglen + datalen > skb->len) {
1848 /* message too short for announced data length */
1849 send_conf(iif, ap, skb, CapiIllMessageParmCoding); /* ? */
1850 return;
1851 }
1852 if (flags & CAPI_FLAGS_RESERVED) {
1853 dev_notice(cs->dev, "%s: reserved flags set (%x)\n",
1854 "DATA_B3_REQ", flags);
1855 send_conf(iif, ap, skb, CapiIllMessageParmCoding);
1856 return;
1857 }
1858
1859 /* reject if logical connection not active */
1860 if (ap->connected < APCONN_ACTIVE) {
1861 send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
1862 return;
1863 }
1864
1865 /*
1866 * pull CAPI message from skb,
1867 * pass payload data to device-specific module
1868 * CAPI message will be preserved in headroom
1869 */
1870 skb_pull(skb, msglen);
1871 if (cs->ops->send_skb(&cs->bcs[channel-1], skb) < 0) {
1872 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1873 return;
1874 }
1875
1876 /* DATA_B3_CONF reply will be sent by gigaset_skb_sent() */
1877
1878 /*
1879 * ToDo: honor unset "delivery confirmation" bit
1880 * (send DATA_B3_CONF immediately?)
1881 */
1882}
1883
1884/*
1885 * process RESET_B3_REQ message
1886 * just always reply "not supported by current protocol"
1887 */
1888static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
1889 struct gigaset_capi_appl *ap,
1890 struct sk_buff *skb)
1891{
1892 /* decode message */
1893 capi_message2cmsg(&iif->acmsg, skb->data);
1894 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1895 send_conf(iif, ap, skb,
1896 CapiResetProcedureNotSupportedByCurrentProtocol);
1897}
1898
1899/*
1900 * dump unsupported/ignored messages at most twice per minute,
1901 * some apps send those very frequently
1902 */
1903static unsigned long ignored_msg_dump_time;
1904
1905/*
1906 * unsupported CAPI message handler
1907 */
1908static void do_unsupported(struct gigaset_capi_ctr *iif,
1909 struct gigaset_capi_appl *ap,
1910 struct sk_buff *skb)
1911{
1912 /* decode message */
1913 capi_message2cmsg(&iif->acmsg, skb->data);
1914 if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000))
1915 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1916 send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
1917}
1918
1919/*
1920 * CAPI message handler: no-op
1921 */
1922static void do_nothing(struct gigaset_capi_ctr *iif,
1923 struct gigaset_capi_appl *ap,
1924 struct sk_buff *skb)
1925{
1926 if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) {
1927 /* decode message */
1928 capi_message2cmsg(&iif->acmsg, skb->data);
1929 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1930 }
1931 dev_kfree_skb(skb);
1932}
1933
1934static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
1935 struct gigaset_capi_appl *ap,
1936 struct sk_buff *skb)
1937{
1938 dump_rawmsg(DEBUG_LLDATA, __func__, skb->data);
1939 dev_kfree_skb(skb);
1940}
1941
1942/* table of outgoing CAPI message handlers with lookup function */
1943typedef void (*capi_send_handler_t)(struct gigaset_capi_ctr *,
1944 struct gigaset_capi_appl *,
1945 struct sk_buff *);
1946
1947static struct {
1948 u16 cmd;
1949 capi_send_handler_t handler;
1950} capi_send_handler_table[] = {
1951 /* most frequent messages first for faster lookup */
1952 { CAPI_DATA_B3_REQ, do_data_b3_req },
1953 { CAPI_DATA_B3_RESP, do_data_b3_resp },
1954
1955 { CAPI_ALERT_REQ, do_alert_req },
1956 { CAPI_CONNECT_ACTIVE_RESP, do_nothing },
1957 { CAPI_CONNECT_B3_ACTIVE_RESP, do_nothing },
1958 { CAPI_CONNECT_B3_REQ, do_connect_b3_req },
1959 { CAPI_CONNECT_B3_RESP, do_connect_b3_resp },
1960 { CAPI_CONNECT_B3_T90_ACTIVE_RESP, do_nothing },
1961 { CAPI_CONNECT_REQ, do_connect_req },
1962 { CAPI_CONNECT_RESP, do_connect_resp },
1963 { CAPI_DISCONNECT_B3_REQ, do_disconnect_b3_req },
1964 { CAPI_DISCONNECT_B3_RESP, do_nothing },
1965 { CAPI_DISCONNECT_REQ, do_disconnect_req },
1966 { CAPI_DISCONNECT_RESP, do_nothing },
1967 { CAPI_FACILITY_REQ, do_facility_req },
1968 { CAPI_FACILITY_RESP, do_nothing },
1969 { CAPI_LISTEN_REQ, do_listen_req },
1970 { CAPI_SELECT_B_PROTOCOL_REQ, do_unsupported },
1971 { CAPI_RESET_B3_REQ, do_reset_b3_req },
1972 { CAPI_RESET_B3_RESP, do_nothing },
1973
1974 /*
1975 * ToDo: support overlap sending (requires ev-layer state
1976 * machine extension to generate additional ATD commands)
1977 */
1978 { CAPI_INFO_REQ, do_unsupported },
1979 { CAPI_INFO_RESP, do_nothing },
1980
1981 /*
1982 * ToDo: what's the proper response for these?
1983 */
1984 { CAPI_MANUFACTURER_REQ, do_nothing },
1985 { CAPI_MANUFACTURER_RESP, do_nothing },
1986};
1987
1988/* look up handler */
1989static inline capi_send_handler_t lookup_capi_send_handler(const u16 cmd)
1990{
1991 size_t i;
1992
1993 for (i = 0; i < ARRAY_SIZE(capi_send_handler_table); i++)
1994 if (capi_send_handler_table[i].cmd == cmd)
1995 return capi_send_handler_table[i].handler;
1996 return NULL;
1997}
1998
1999
2000/**
2001 * gigaset_send_message() - accept a CAPI message from an application
2002 * @ctr: controller descriptor structure.
2003 * @skb: CAPI message.
2004 *
2005 * Return value: CAPI error code
2006 * Note: capidrv (and probably others, too) only uses the return value to
2007 * decide whether it has to free the skb (only if result != CAPI_NOERROR (0))
2008 */
2009static u16 gigaset_send_message(struct capi_ctr *ctr, struct sk_buff *skb)
2010{
2011 struct gigaset_capi_ctr *iif
2012 = container_of(ctr, struct gigaset_capi_ctr, ctr);
2013 struct cardstate *cs = ctr->driverdata;
2014 struct gigaset_capi_appl *ap;
2015 capi_send_handler_t handler;
2016
2017 /* can only handle linear sk_buffs */
2018 if (skb_linearize(skb) < 0) {
2019 dev_warn(cs->dev, "%s: skb_linearize failed\n", __func__);
2020 return CAPI_MSGOSRESOURCEERR;
2021 }
2022
2023 /* retrieve application data structure */
2024 ap = get_appl(iif, CAPIMSG_APPID(skb->data));
2025 if (!ap) {
2026 dev_notice(cs->dev, "%s: application %u not registered\n",
2027 __func__, CAPIMSG_APPID(skb->data));
2028 return CAPI_ILLAPPNR;
2029 }
2030
2031 /* look up command */
2032 handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
2033 if (!handler) {
2034 /* unknown/unsupported message type */
2035 if (printk_ratelimit())
2036 dev_notice(cs->dev, "%s: unsupported message %u\n",
2037 __func__, CAPIMSG_CMD(skb->data));
2038 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
2039 }
2040
2041 /* serialize */
2042 if (atomic_add_return(1, &iif->sendqlen) > 1) {
2043 /* queue behind other messages */
2044 skb_queue_tail(&iif->sendqueue, skb);
2045 return CAPI_NOERROR;
2046 }
2047
2048 /* process message */
2049 handler(iif, ap, skb);
2050
2051 /* process other messages arrived in the meantime */
2052 while (atomic_sub_return(1, &iif->sendqlen) > 0) {
2053 skb = skb_dequeue(&iif->sendqueue);
2054 if (!skb) {
2055 /* should never happen */
2056 dev_err(cs->dev, "%s: send queue empty\n", __func__);
2057 continue;
2058 }
2059 ap = get_appl(iif, CAPIMSG_APPID(skb->data));
2060 if (!ap) {
2061 /* could that happen? */
2062 dev_warn(cs->dev, "%s: application %u vanished\n",
2063 __func__, CAPIMSG_APPID(skb->data));
2064 continue;
2065 }
2066 handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
2067 if (!handler) {
2068 /* should never happen */
2069 dev_err(cs->dev, "%s: handler %x vanished\n",
2070 __func__, CAPIMSG_CMD(skb->data));
2071 continue;
2072 }
2073 handler(iif, ap, skb);
2074 }
2075
2076 return CAPI_NOERROR;
2077}
2078
2079/**
2080 * gigaset_procinfo() - build single line description for controller
2081 * @ctr: controller descriptor structure.
2082 *
2083 * Return value: pointer to generated string (null terminated)
2084 */
2085static char *gigaset_procinfo(struct capi_ctr *ctr)
2086{
2087 return ctr->name; /* ToDo: more? */
2088}
2089
2090/**
2091 * gigaset_ctr_read_proc() - build controller proc file entry
2092 * @page: buffer of PAGE_SIZE bytes for receiving the entry.
2093 * @start: unused.
2094 * @off: unused.
2095 * @count: unused.
2096 * @eof: unused.
2097 * @ctr: controller descriptor structure.
2098 *
2099 * Return value: length of generated entry
2100 */
2101static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
2102 int count, int *eof, struct capi_ctr *ctr)
2103{
2104 struct cardstate *cs = ctr->driverdata;
2105 char *s;
2106 int i;
2107 int len = 0;
2108 len += sprintf(page+len, "%-16s %s\n", "name", ctr->name);
2109 len += sprintf(page+len, "%-16s %s %s\n", "dev",
2110 dev_driver_string(cs->dev), dev_name(cs->dev));
2111 len += sprintf(page+len, "%-16s %d\n", "id", cs->myid);
2112 if (cs->gotfwver)
2113 len += sprintf(page+len, "%-16s %d.%d.%d.%d\n", "firmware",
2114 cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
2115 len += sprintf(page+len, "%-16s %d\n", "channels",
2116 cs->channels);
2117 len += sprintf(page+len, "%-16s %s\n", "onechannel",
2118 cs->onechannel ? "yes" : "no");
2119
2120 switch (cs->mode) {
2121 case M_UNKNOWN:
2122 s = "unknown";
2123 break;
2124 case M_CONFIG:
2125 s = "config";
2126 break;
2127 case M_UNIMODEM:
2128 s = "Unimodem";
2129 break;
2130 case M_CID:
2131 s = "CID";
2132 break;
2133 default:
2134 s = "??";
2135 }
2136 len += sprintf(page+len, "%-16s %s\n", "mode", s);
2137
2138 switch (cs->mstate) {
2139 case MS_UNINITIALIZED:
2140 s = "uninitialized";
2141 break;
2142 case MS_INIT:
2143 s = "init";
2144 break;
2145 case MS_LOCKED:
2146 s = "locked";
2147 break;
2148 case MS_SHUTDOWN:
2149 s = "shutdown";
2150 break;
2151 case MS_RECOVER:
2152 s = "recover";
2153 break;
2154 case MS_READY:
2155 s = "ready";
2156 break;
2157 default:
2158 s = "??";
2159 }
2160 len += sprintf(page+len, "%-16s %s\n", "mstate", s);
2161
2162 len += sprintf(page+len, "%-16s %s\n", "running",
2163 cs->running ? "yes" : "no");
2164 len += sprintf(page+len, "%-16s %s\n", "connected",
2165 cs->connected ? "yes" : "no");
2166 len += sprintf(page+len, "%-16s %s\n", "isdn_up",
2167 cs->isdn_up ? "yes" : "no");
2168 len += sprintf(page+len, "%-16s %s\n", "cidmode",
2169 cs->cidmode ? "yes" : "no");
2170
2171 for (i = 0; i < cs->channels; i++) {
2172 len += sprintf(page+len, "[%d]%-13s %d\n", i, "corrupted",
2173 cs->bcs[i].corrupted);
2174 len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_down",
2175 cs->bcs[i].trans_down);
2176 len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_up",
2177 cs->bcs[i].trans_up);
2178 len += sprintf(page+len, "[%d]%-13s %d\n", i, "chstate",
2179 cs->bcs[i].chstate);
2180 switch (cs->bcs[i].proto2) {
2181 case L2_BITSYNC:
2182 s = "bitsync";
2183 break;
2184 case L2_HDLC:
2185 s = "HDLC";
2186 break;
2187 case L2_VOICE:
2188 s = "voice";
2189 break;
2190 default:
2191 s = "??";
2192 }
2193 len += sprintf(page+len, "[%d]%-13s %s\n", i, "proto2", s);
2194 }
2195 return len;
2196}
2197
2198
2199static struct capi_driver capi_driver_gigaset = {
2200 .name = "gigaset",
2201 .revision = "1.0",
2202};
2203
2204/**
2205 * gigaset_isdn_register() - register to LL
2206 * @cs: device descriptor structure.
2207 * @isdnid: device name.
2208 *
2209 * Called by main module to register the device with the LL.
2210 *
2211 * Return value: 1 for success, 0 for failure
2212 */
2213int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
2214{
2215 struct gigaset_capi_ctr *iif;
2216 int rc;
2217
2218 pr_info("Kernel CAPI interface\n");
2219
2220 iif = kmalloc(sizeof(*iif), GFP_KERNEL);
2221 if (!iif) {
2222 pr_err("%s: out of memory\n", __func__);
2223 return 0;
2224 }
2225
2226 /* register driver with CAPI (ToDo: what for?) */
2227 register_capi_driver(&capi_driver_gigaset);
2228
2229 /* prepare controller structure */
2230 iif->ctr.owner = THIS_MODULE;
2231 iif->ctr.driverdata = cs;
2232 strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name));
2233 iif->ctr.driver_name = "gigaset";
2234 iif->ctr.load_firmware = gigaset_load_firmware;
2235 iif->ctr.reset_ctr = gigaset_reset_ctr;
2236 iif->ctr.register_appl = gigaset_register_appl;
2237 iif->ctr.release_appl = gigaset_release_appl;
2238 iif->ctr.send_message = gigaset_send_message;
2239 iif->ctr.procinfo = gigaset_procinfo;
2240 iif->ctr.ctr_read_proc = gigaset_ctr_read_proc;
2241 INIT_LIST_HEAD(&iif->appls);
2242 skb_queue_head_init(&iif->sendqueue);
2243 atomic_set(&iif->sendqlen, 0);
2244
2245 /* register controller with CAPI */
2246 rc = attach_capi_ctr(&iif->ctr);
2247 if (rc) {
2248 pr_err("attach_capi_ctr failed (%d)\n", rc);
2249 unregister_capi_driver(&capi_driver_gigaset);
2250 kfree(iif);
2251 return 0;
2252 }
2253
2254 cs->iif = iif;
2255 cs->hw_hdr_len = CAPI_DATA_B3_REQ_LEN;
2256 return 1;
2257}
2258
2259/**
2260 * gigaset_isdn_unregister() - unregister from LL
2261 * @cs: device descriptor structure.
2262 *
2263 * Called by main module to unregister the device from the LL.
2264 */
2265void gigaset_isdn_unregister(struct cardstate *cs)
2266{
2267 struct gigaset_capi_ctr *iif = cs->iif;
2268
2269 detach_capi_ctr(&iif->ctr);
2270 kfree(iif);
2271 cs->iif = NULL;
2272 unregister_capi_driver(&capi_driver_gigaset);
2273}
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 15dc0fc28a96..1d2ae2e05e0b 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -207,6 +207,32 @@ int gigaset_get_channel(struct bc_state *bcs)
207 return 1; 207 return 1;
208} 208}
209 209
210struct bc_state *gigaset_get_free_channel(struct cardstate *cs)
211{
212 unsigned long flags;
213 int i;
214
215 spin_lock_irqsave(&cs->lock, flags);
216 if (!try_module_get(cs->driver->owner)) {
217 gig_dbg(DEBUG_ANY,
218 "could not get module for allocating channel");
219 spin_unlock_irqrestore(&cs->lock, flags);
220 return NULL;
221 }
222 for (i = 0; i < cs->channels; ++i)
223 if (!cs->bcs[i].use_count) {
224 ++cs->bcs[i].use_count;
225 cs->bcs[i].busy = 1;
226 spin_unlock_irqrestore(&cs->lock, flags);
227 gig_dbg(DEBUG_ANY, "allocated channel %d", i);
228 return cs->bcs + i;
229 }
230 module_put(cs->driver->owner);
231 spin_unlock_irqrestore(&cs->lock, flags);
232 gig_dbg(DEBUG_ANY, "no free channel");
233 return NULL;
234}
235
210void gigaset_free_channel(struct bc_state *bcs) 236void gigaset_free_channel(struct bc_state *bcs)
211{ 237{
212 unsigned long flags; 238 unsigned long flags;
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index cb25d2b834b9..369927f90729 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -291,21 +291,23 @@ struct reply_t gigaset_tab_cid[] =
291 {RSP_OK, 602,602, -1, 603, 5, {ACT_CMD+AT_PROTO}}, 291 {RSP_OK, 602,602, -1, 603, 5, {ACT_CMD+AT_PROTO}},
292 {RSP_OK, 603,603, -1, 604, 5, {ACT_CMD+AT_TYPE}}, 292 {RSP_OK, 603,603, -1, 604, 5, {ACT_CMD+AT_TYPE}},
293 {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}}, 293 {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}},
294 {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, 294 {RSP_NULL, 605, 605, -1, 606, 5, {ACT_CMD+AT_CLIP} },
295 {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, 295 {RSP_OK, 605, 605, -1, 606, 5, {ACT_CMD+AT_CLIP} },
296 {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, 296 {RSP_NULL, 606, 606, -1, 607, 5, {ACT_CMD+AT_ISO} },
297 {RSP_OK, 607,607, -1, 608,-1}, 297 {RSP_OK, 606, 606, -1, 607, 5, {ACT_CMD+AT_ISO} },
298 {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}}, 298 {RSP_OK, 607, 607, -1, 608, 5, {0}, "+VLS=17\r"},
299 {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}}, 299 {RSP_OK, 608, 608, -1, 609, -1},
300 300 {RSP_ZSAU, 609, 609, ZSAU_PROCEEDING, 610, 5, {ACT_CMD+AT_DIAL} },
301 {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, 301 {RSP_OK, 610, 610, -1, 650, 0, {ACT_DIALING} },
302 {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, 302
303 {RSP_ERROR, 601, 610, -1, 0, 0, {ACT_ABORTDIAL} },
304 {EV_TIMEOUT, 601, 610, -1, 0, 0, {ACT_ABORTDIAL} },
303 305
304 /* optional dialing responses */ 306 /* optional dialing responses */
305 {EV_BC_OPEN, 650,650, -1, 651,-1}, 307 {EV_BC_OPEN, 650,650, -1, 651,-1},
306 {RSP_ZVLS, 608,651, 17, -1,-1, {ACT_DEBUG}}, 308 {RSP_ZVLS, 609, 651, 17, -1, -1, {ACT_DEBUG} },
307 {RSP_ZCTP, 609,651, -1, -1,-1, {ACT_DEBUG}}, 309 {RSP_ZCTP, 610, 651, -1, -1, -1, {ACT_DEBUG} },
308 {RSP_ZCPN, 609,651, -1, -1,-1, {ACT_DEBUG}}, 310 {RSP_ZCPN, 610, 651, -1, -1, -1, {ACT_DEBUG} },
309 {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, 311 {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}},
310 312
311 /* connect */ 313 /* connect */
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 1185da2dbf61..4749ef100fd3 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -191,7 +191,9 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
191#define AT_PROTO 4 191#define AT_PROTO 4
192#define AT_TYPE 5 192#define AT_TYPE 5
193#define AT_HLC 6 193#define AT_HLC 6
194#define AT_NUM 7 194#define AT_CLIP 7
195/* total number */
196#define AT_NUM 8
195 197
196/* variables in struct at_state_t */ 198/* variables in struct at_state_t */
197#define VAR_ZSAU 0 199#define VAR_ZSAU 0
@@ -412,6 +414,8 @@ struct bc_state {
412 struct usb_bc_state *usb; /* usb hardware driver (m105) */ 414 struct usb_bc_state *usb; /* usb hardware driver (m105) */
413 struct bas_bc_state *bas; /* usb hardware driver (base) */ 415 struct bas_bc_state *bas; /* usb hardware driver (base) */
414 } hw; 416 } hw;
417
418 void *ap; /* LL application structure */
415}; 419};
416 420
417struct cardstate { 421struct cardstate {
@@ -725,6 +729,7 @@ void gigaset_bcs_reinit(struct bc_state *bcs);
725void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, 729void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
726 struct cardstate *cs, int cid); 730 struct cardstate *cs, int cid);
727int gigaset_get_channel(struct bc_state *bcs); 731int gigaset_get_channel(struct bc_state *bcs);
732struct bc_state *gigaset_get_free_channel(struct cardstate *cs);
728void gigaset_free_channel(struct bc_state *bcs); 733void gigaset_free_channel(struct bc_state *bcs);
729int gigaset_get_channels(struct cardstate *cs); 734int gigaset_get_channels(struct cardstate *cs);
730void gigaset_free_channels(struct cardstate *cs); 735void gigaset_free_channels(struct cardstate *cs);