aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn/gigaset/capi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/gigaset/capi.c')
-rw-r--r--drivers/isdn/gigaset/capi.c363
1 files changed, 194 insertions, 169 deletions
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 6fbe8999c41..3286903a95d 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -14,9 +14,11 @@
#include "gigaset.h"
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/ratelimit.h>
#include <linux/isdn/capilli.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>
+#include <linux/export.h>
/* missing from kernelcapi.h */
#define CapiNcpiNotSupportedByProtocol 0x0001
@@ -25,17 +27,17 @@
#define CapiFacilitySpecificFunctionNotSupported 0x3011
/* missing from capicmd.h */
-#define CAPI_CONNECT_IND_BASELEN (CAPI_MSG_BASELEN+4+2+8*1)
-#define CAPI_CONNECT_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN+4+3*1)
-#define CAPI_CONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN+4+1)
-#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN+4+1)
-#define CAPI_DATA_B3_REQ_LEN64 (CAPI_MSG_BASELEN+4+4+2+2+2+8)
-#define CAPI_DATA_B3_CONF_LEN (CAPI_MSG_BASELEN+4+2+2)
-#define CAPI_DISCONNECT_IND_LEN (CAPI_MSG_BASELEN+4+2)
-#define CAPI_DISCONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN+4+2+1)
-#define CAPI_FACILITY_CONF_BASELEN (CAPI_MSG_BASELEN+4+2+2+1)
+#define CAPI_CONNECT_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 8 * 1)
+#define CAPI_CONNECT_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 3 * 1)
+#define CAPI_CONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 1)
+#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 1)
+#define CAPI_DATA_B3_REQ_LEN64 (CAPI_MSG_BASELEN + 4 + 4 + 2 + 2 + 2 + 8)
+#define CAPI_DATA_B3_CONF_LEN (CAPI_MSG_BASELEN + 4 + 2 + 2)
+#define CAPI_DISCONNECT_IND_LEN (CAPI_MSG_BASELEN + 4 + 2)
+#define CAPI_DISCONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 1)
+#define CAPI_FACILITY_CONF_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 2 + 1)
/* most _CONF messages contain only Controller/PLCI/NCCI and Info parameters */
-#define CAPI_STDCONF_LEN (CAPI_MSG_BASELEN+4+2)
+#define CAPI_STDCONF_LEN (CAPI_MSG_BASELEN + 4 + 2)
#define CAPI_FACILITY_HANDSET 0x0000
#define CAPI_FACILITY_DTMF 0x0001
@@ -45,6 +47,7 @@
#define CAPI_FACILITY_LI 0x0005
#define CAPI_SUPPSVC_GETSUPPORTED 0x0000
+#define CAPI_SUPPSVC_LISTEN 0x0001
/* missing from capiutil.h */
#define CAPIMSG_PLCI_PART(m) CAPIMSG_U8(m, 9)
@@ -95,10 +98,10 @@ struct gigaset_capi_ctr {
/* two _cmsg structures possibly used concurrently: */
_cmsg hcmsg; /* for message composition triggered from hardware */
_cmsg acmsg; /* for dissection of messages sent from application */
- u8 bc_buf[MAX_BC_OCTETS+1];
- u8 hlc_buf[MAX_HLC_OCTETS+1];
- u8 cgpty_buf[MAX_NUMBER_DIGITS+3];
- u8 cdpty_buf[MAX_NUMBER_DIGITS+2];
+ u8 bc_buf[MAX_BC_OCTETS + 1];
+ u8 hlc_buf[MAX_HLC_OCTETS + 1];
+ u8 cgpty_buf[MAX_NUMBER_DIGITS + 3];
+ u8 cdpty_buf[MAX_NUMBER_DIGITS + 2];
};
/* CIP Value table (from CAPI 2.0 standard, ch. 6.1) */
@@ -106,51 +109,35 @@ static struct {
u8 *bc;
u8 *hlc;
} cip2bchlc[] = {
- [1] = { "8090A3", NULL },
- /* Speech (A-law) */
- [2] = { "8890", NULL },
- /* Unrestricted digital information */
- [3] = { "8990", NULL },
- /* Restricted digital information */
- [4] = { "9090A3", NULL },
- /* 3,1 kHz audio (A-law) */
- [5] = { "9190", NULL },
- /* 7 kHz audio */
- [6] = { "9890", NULL },
- /* Video */
- [7] = { "88C0C6E6", NULL },
- /* Packet mode */
- [8] = { "8890218F", NULL },
- /* 56 kbit/s rate adaptation */
- [9] = { "9190A5", NULL },
- /* Unrestricted digital information with tones/announcements */
- [16] = { "8090A3", "9181" },
- /* Telephony */
- [17] = { "9090A3", "9184" },
- /* Group 2/3 facsimile */
- [18] = { "8890", "91A1" },
- /* Group 4 facsimile Class 1 */
- [19] = { "8890", "91A4" },
- /* Teletex service basic and mixed mode
- and Group 4 facsimile service Classes II and III */
- [20] = { "8890", "91A8" },
- /* Teletex service basic and processable mode */
- [21] = { "8890", "91B1" },
- /* Teletex service basic mode */
- [22] = { "8890", "91B2" },
- /* International interworking for Videotex */
- [23] = { "8890", "91B5" },
- /* Telex */
- [24] = { "8890", "91B8" },
- /* Message Handling Systems in accordance with X.400 */
- [25] = { "8890", "91C1" },
- /* OSI application in accordance with X.200 */
- [26] = { "9190A5", "9181" },
- /* 7 kHz telephony */
- [27] = { "9190A5", "916001" },
- /* Video telephony, first connection */
- [28] = { "8890", "916002" },
- /* Video telephony, second connection */
+ [1] = { "8090A3", NULL }, /* Speech (A-law) */
+ [2] = { "8890", NULL }, /* Unrestricted digital information */
+ [3] = { "8990", NULL }, /* Restricted digital information */
+ [4] = { "9090A3", NULL }, /* 3,1 kHz audio (A-law) */
+ [5] = { "9190", NULL }, /* 7 kHz audio */
+ [6] = { "9890", NULL }, /* Video */
+ [7] = { "88C0C6E6", NULL }, /* Packet mode */
+ [8] = { "8890218F", NULL }, /* 56 kbit/s rate adaptation */
+ [9] = { "9190A5", NULL }, /* Unrestricted digital information
+ * with tones/announcements */
+ [16] = { "8090A3", "9181" }, /* Telephony */
+ [17] = { "9090A3", "9184" }, /* Group 2/3 facsimile */
+ [18] = { "8890", "91A1" }, /* Group 4 facsimile Class 1 */
+ [19] = { "8890", "91A4" }, /* Teletex service basic and mixed mode
+ * and Group 4 facsimile service
+ * Classes II and III */
+ [20] = { "8890", "91A8" }, /* Teletex service basic and
+ * processable mode */
+ [21] = { "8890", "91B1" }, /* Teletex service basic mode */
+ [22] = { "8890", "91B2" }, /* International interworking for
+ * Videotex */
+ [23] = { "8890", "91B5" }, /* Telex */
+ [24] = { "8890", "91B8" }, /* Message Handling Systems
+ * in accordance with X.400 */
+ [25] = { "8890", "91C1" }, /* OSI application
+ * in accordance with X.200 */
+ [26] = { "9190A5", "9181" }, /* 7 kHz telephony */
+ [27] = { "9190A5", "916001" }, /* Video telephony, first connection */
+ [28] = { "8890", "916002" }, /* Video telephony, second connection */
};
/*
@@ -162,7 +149,7 @@ static struct {
* emit unsupported parameter warning
*/
static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
- char *msgname, char *paramname)
+ char *msgname, char *paramname)
{
if (param && *param)
dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
@@ -221,10 +208,14 @@ get_appl(struct gigaset_capi_ctr *iif, u16 appl)
static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p)
{
#ifdef CONFIG_GIGASET_DEBUG
+ /* dump at most 20 messages in 20 secs */
+ static DEFINE_RATELIMIT_STATE(msg_dump_ratelimit, 20 * HZ, 20);
_cdebbuf *cdb;
if (!(gigaset_debuglevel & level))
return;
+ if (!___ratelimit(&msg_dump_ratelimit, tag))
+ return;
cdb = capi_cmsg2str(p);
if (cdb) {
@@ -257,32 +248,38 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
CAPIMSG_CONTROL(data));
l -= 12;
- dbgline = kmalloc(3*l, GFP_ATOMIC);
+ if (l <= 0)
+ return;
+ dbgline = kmalloc(3 * l, GFP_ATOMIC);
if (!dbgline)
return;
for (i = 0; i < l; i++) {
- dbgline[3*i] = hex_asc_hi(data[12+i]);
- dbgline[3*i+1] = hex_asc_lo(data[12+i]);
- dbgline[3*i+2] = ' ';
+ dbgline[3 * i] = hex_asc_hi(data[12 + i]);
+ dbgline[3 * i + 1] = hex_asc_lo(data[12 + i]);
+ dbgline[3 * i + 2] = ' ';
}
- dbgline[3*l-1] = '\0';
+ dbgline[3 * l - 1] = '\0';
gig_dbg(level, " %s", dbgline);
kfree(dbgline);
if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
(CAPIMSG_SUBCOMMAND(data) == CAPI_REQ ||
- CAPIMSG_SUBCOMMAND(data) == CAPI_IND) &&
- CAPIMSG_DATALEN(data) > 0) {
+ CAPIMSG_SUBCOMMAND(data) == CAPI_IND)) {
l = CAPIMSG_DATALEN(data);
- dbgline = kmalloc(3*l, GFP_ATOMIC);
+ gig_dbg(level, " DataLength=%d", l);
+ if (l <= 0 || !(gigaset_debuglevel & DEBUG_LLDATA))
+ return;
+ if (l > 64)
+ l = 64; /* arbitrary limit */
+ dbgline = kmalloc(3 * l, GFP_ATOMIC);
if (!dbgline)
return;
data += CAPIMSG_LEN(data);
for (i = 0; i < l; i++) {
- dbgline[3*i] = hex_asc_hi(data[i]);
- dbgline[3*i+1] = hex_asc_lo(data[i]);
- dbgline[3*i+2] = ' ';
+ dbgline[3 * i] = hex_asc_hi(data[i]);
+ dbgline[3 * i + 1] = hex_asc_lo(data[i]);
+ dbgline[3 * i + 2] = ' ';
}
- dbgline[3*l-1] = '\0';
+ dbgline[3 * l - 1] = '\0';
gig_dbg(level, " %s", dbgline);
kfree(dbgline);
}
@@ -293,9 +290,10 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
* format CAPI IE as string
*/
+#ifdef CONFIG_GIGASET_DEBUG
static const char *format_ie(const char *ie)
{
- static char result[3*MAX_FMT_IE_LEN];
+ static char result[3 * MAX_FMT_IE_LEN];
int len, count;
char *pout = result;
@@ -304,7 +302,7 @@ static const char *format_ie(const char *ie)
count = len = ie[0];
if (count > MAX_FMT_IE_LEN)
- count = MAX_FMT_IE_LEN-1;
+ count = MAX_FMT_IE_LEN - 1;
while (count--) {
*pout++ = hex_asc_hi(*++ie);
*pout++ = hex_asc_lo(*ie);
@@ -318,6 +316,7 @@ static const char *format_ie(const char *ie)
*--pout = 0;
return result;
}
+#endif
/*
* emit DATA_B3_CONF message
@@ -378,13 +377,13 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
++bcs->trans_up;
if (!ap) {
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
return;
}
/* don't send further B3 messages if disconnected */
if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
+ gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
return;
}
@@ -397,8 +396,8 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req),
bcs->channel + 1, CAPIMSG_HANDLE_REQ(req),
(flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ?
- CapiFlagsNotSupportedByProtocol :
- CAPI_NOERROR);
+ CapiFlagsNotSupportedByProtocol :
+ CAPI_NOERROR);
}
EXPORT_SYMBOL_GPL(gigaset_skb_sent);
@@ -422,13 +421,14 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
bcs->trans_down++;
if (!ap) {
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
+ dev_kfree_skb_any(skb);
return;
}
/* don't send further B3 messages if disconnected */
if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_LLDATA, "disconnected, discarding data");
+ gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
dev_kfree_skb_any(skb);
return;
}
@@ -454,7 +454,7 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
/* Data64 parameter not present */
/* emit message */
- dump_rawmsg(DEBUG_LLDATA, "DATA_B3_IND", skb->data);
+ dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
@@ -582,7 +582,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
}
iif->cdpty_buf[0] = i + 1;
iif->cdpty_buf[1] = 0x80; /* type / numbering plan unknown */
- memcpy(iif->cdpty_buf+2, at_state->str_var[STR_ZCPN], i);
+ memcpy(iif->cdpty_buf + 2, at_state->str_var[STR_ZCPN], i);
iif->hcmsg.CalledPartyNumber = iif->cdpty_buf;
msgsize += iif->hcmsg.CalledPartyNumber[0];
}
@@ -598,7 +598,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
iif->cgpty_buf[0] = i + 2;
iif->cgpty_buf[1] = 0x00; /* type / numbering plan unknown */
iif->cgpty_buf[2] = 0x80; /* pres. allowed, not screened */
- memcpy(iif->cgpty_buf+3, at_state->str_var[STR_NMBR], i);
+ memcpy(iif->cgpty_buf + 3, at_state->str_var[STR_NMBR], i);
iif->hcmsg.CallingPartyNumber = iif->cgpty_buf;
msgsize += iif->hcmsg.CallingPartyNumber[0];
}
@@ -747,7 +747,7 @@ void gigaset_isdn_connD(struct bc_state *bcs)
ap = bcs->ap;
if (!ap) {
spin_unlock_irqrestore(&bcs->aplock, flags);
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
return;
}
if (bcs->apconnstate == APCONN_NONE) {
@@ -843,7 +843,7 @@ void gigaset_isdn_connB(struct bc_state *bcs)
ap = bcs->ap;
if (!ap) {
spin_unlock_irqrestore(&bcs->aplock, flags);
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
return;
}
if (!bcs->apconnstate) {
@@ -901,13 +901,12 @@ void gigaset_isdn_connB(struct bc_state *bcs)
*/
void gigaset_isdn_hupB(struct bc_state *bcs)
{
- struct cardstate *cs = bcs->cs;
struct gigaset_capi_appl *ap = bcs->ap;
/* ToDo: assure order of DISCONNECT_B3_IND and DISCONNECT_IND ? */
if (!ap) {
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
return;
}
@@ -971,13 +970,16 @@ void gigaset_isdn_stop(struct cardstate *cs)
* register CAPI application
*/
static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
- capi_register_params *rp)
+ capi_register_params *rp)
{
struct gigaset_capi_ctr *iif
= container_of(ctr, struct gigaset_capi_ctr, ctr);
struct cardstate *cs = ctr->driverdata;
struct gigaset_capi_appl *ap;
+ gig_dbg(DEBUG_CMD, "%s [%u] l3cnt=%u blkcnt=%u blklen=%u",
+ __func__, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
+
list_for_each_entry(ap, &iif->appls, ctrlist)
if (ap->id == appl) {
dev_notice(cs->dev,
@@ -1044,6 +1046,7 @@ static inline void remove_appl_from_channel(struct bc_state *bcs,
do {
if (bcap->bcnext == ap) {
bcap->bcnext = bcap->bcnext->bcnext;
+ spin_unlock_irqrestore(&bcs->aplock, flags);
return;
}
bcap = bcap->bcnext;
@@ -1062,6 +1065,8 @@ static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
struct gigaset_capi_appl *ap, *tmp;
unsigned ch;
+ gig_dbg(DEBUG_CMD, "%s [%u]", __func__, appl);
+
list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
if (ap->id == appl) {
/* remove from any channels */
@@ -1142,7 +1147,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
case CAPI_FACILITY_SUPPSVC:
/* decode Function parameter */
pparam = cmsg->FacilityRequestParameter;
- if (pparam == NULL || *pparam < 2) {
+ if (pparam == NULL || pparam[0] < 2) {
dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
"Facility Request Parameter");
send_conf(iif, ap, skb, CapiIllMessageParmCoding);
@@ -1159,8 +1164,34 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
/* Supported Services: none */
capimsg_setu32(confparam, 6, 0);
break;
+ case CAPI_SUPPSVC_LISTEN:
+ if (pparam[0] < 7 || pparam[3] < 4) {
+ dev_notice(cs->dev, "%s: %s missing\n",
+ "FACILITY_REQ", "Notification Mask");
+ send_conf(iif, ap, skb,
+ CapiIllMessageParmCoding);
+ return;
+ }
+ if (CAPIMSG_U32(pparam, 4) != 0) {
+ dev_notice(cs->dev,
+ "%s: unsupported supplementary service notification mask 0x%x\n",
+ "FACILITY_REQ", CAPIMSG_U32(pparam, 4));
+ info = CapiFacilitySpecificFunctionNotSupported;
+ confparam[3] = 2; /* length */
+ capimsg_setu16(confparam, 4,
+ CapiSupplementaryServiceNotSupported);
+ }
+ info = CapiSuccess;
+ confparam[3] = 2; /* length */
+ capimsg_setu16(confparam, 4, CapiSuccess);
+ break;
+
/* ToDo: add supported services */
+
default:
+ dev_notice(cs->dev,
+ "%s: unsupported supplementary service function 0x%04x\n",
+ "FACILITY_REQ", function);
info = CapiFacilitySpecificFunctionNotSupported;
/* Supplementary Service specific parameter */
confparam[3] = 2; /* length */
@@ -1282,7 +1313,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;
/* build command table */
- commands = kzalloc(AT_NUM*(sizeof *commands), GFP_KERNEL);
+ commands = kzalloc(AT_NUM * (sizeof *commands), GFP_KERNEL);
if (!commands)
goto oom;
@@ -1317,10 +1348,10 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
commands[AT_TYPE] = kstrdup(s, GFP_KERNEL);
if (!commands[AT_TYPE])
goto oom;
- commands[AT_DIAL] = kmalloc(l+3, GFP_KERNEL);
+ commands[AT_DIAL] = kmalloc(l + 3, GFP_KERNEL);
if (!commands[AT_DIAL])
goto oom;
- snprintf(commands[AT_DIAL], l+3, "D%.*s\r", l, pp);
+ snprintf(commands[AT_DIAL], l + 3, "D%.*s\r", l, pp);
/* encode parameter: Calling party number */
pp = cmsg->CallingPartyNumber;
@@ -1370,10 +1401,10 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
if (l) {
/* number */
- commands[AT_MSN] = kmalloc(l+8, GFP_KERNEL);
+ commands[AT_MSN] = kmalloc(l + 8, GFP_KERNEL);
if (!commands[AT_MSN])
goto oom;
- snprintf(commands[AT_MSN], l+8, "^SMSN=%*s\r", l, pp);
+ snprintf(commands[AT_MSN], l + 8, "^SMSN=%*s\r", l, pp);
}
}
@@ -1394,13 +1425,13 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
/* determine lengths */
if (cmsg->BC && cmsg->BC[0]) /* BC specified explicitly */
- lbc = 2*cmsg->BC[0];
+ lbc = 2 * cmsg->BC[0];
else if (cip2bchlc[cmsg->CIPValue].bc) /* BC derived from CIP */
lbc = strlen(cip2bchlc[cmsg->CIPValue].bc);
else /* no BC */
lbc = 0;
if (cmsg->HLC && cmsg->HLC[0]) /* HLC specified explicitly */
- lhlc = 2*cmsg->HLC[0];
+ lhlc = 2 * cmsg->HLC[0];
else if (cip2bchlc[cmsg->CIPValue].hlc) /* HLC derived from CIP */
lhlc = strlen(cip2bchlc[cmsg->CIPValue].hlc);
else /* no HLC */
@@ -1445,7 +1476,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
if (cmsg->BProtocol == CAPI_DEFAULT) {
bcs->proto2 = L2_HDLC;
dev_warn(cs->dev,
- "B2 Protocol X.75 SLP unsupported, using Transparent\n");
+ "B2 Protocol X.75 SLP unsupported, using Transparent\n");
} else {
switch (cmsg->B1protocol) {
case 0:
@@ -1456,24 +1487,24 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
break;
default:
dev_warn(cs->dev,
- "B1 Protocol %u unsupported, using Transparent\n",
+ "B1 Protocol %u unsupported, using Transparent\n",
cmsg->B1protocol);
bcs->proto2 = L2_VOICE;
}
if (cmsg->B2protocol != 1)
dev_warn(cs->dev,
- "B2 Protocol %u unsupported, using Transparent\n",
+ "B2 Protocol %u unsupported, using Transparent\n",
cmsg->B2protocol);
if (cmsg->B3protocol != 0)
dev_warn(cs->dev,
- "B3 Protocol %u unsupported, using Transparent\n",
+ "B3 Protocol %u unsupported, using Transparent\n",
cmsg->B3protocol);
ignore_cstruct_param(cs, cmsg->B1configuration,
- "CONNECT_REQ", "B1 Configuration");
+ "CONNECT_REQ", "B1 Configuration");
ignore_cstruct_param(cs, cmsg->B2configuration,
- "CONNECT_REQ", "B2 Configuration");
+ "CONNECT_REQ", "B2 Configuration");
ignore_cstruct_param(cs, cmsg->B3configuration,
- "CONNECT_REQ", "B3 Configuration");
+ "CONNECT_REQ", "B3 Configuration");
}
commands[AT_PROTO] = kmalloc(9, GFP_KERNEL);
if (!commands[AT_PROTO])
@@ -1482,20 +1513,20 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
/* ToDo: check/encode remaining parameters */
ignore_cstruct_param(cs, cmsg->CalledPartySubaddress,
- "CONNECT_REQ", "Called pty subaddr");
+ "CONNECT_REQ", "Called pty subaddr");
ignore_cstruct_param(cs, cmsg->CallingPartySubaddress,
- "CONNECT_REQ", "Calling pty subaddr");
+ "CONNECT_REQ", "Calling pty subaddr");
ignore_cstruct_param(cs, cmsg->LLC,
- "CONNECT_REQ", "LLC");
+ "CONNECT_REQ", "LLC");
if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
ignore_cstruct_param(cs, cmsg->BChannelinformation,
- "CONNECT_REQ", "B Channel Information");
+ "CONNECT_REQ", "B Channel Information");
ignore_cstruct_param(cs, cmsg->Keypadfacility,
- "CONNECT_REQ", "Keypad Facility");
+ "CONNECT_REQ", "Keypad Facility");
ignore_cstruct_param(cs, cmsg->Useruserdata,
- "CONNECT_REQ", "User-User Data");
+ "CONNECT_REQ", "User-User Data");
ignore_cstruct_param(cs, cmsg->Facilitydataarray,
- "CONNECT_REQ", "Facility Data Array");
+ "CONNECT_REQ", "Facility Data Array");
}
/* encode parameter: B channel to use */
@@ -1566,7 +1597,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
if (oap != ap) {
spin_unlock_irqrestore(&bcs->aplock, flags);
send_disconnect_ind(bcs, oap,
- CapiCallGivenToOtherApplication);
+ CapiCallGivenToOtherApplication);
spin_lock_irqsave(&bcs->aplock, flags);
}
}
@@ -1583,7 +1614,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
if (cmsg->BProtocol == CAPI_DEFAULT) {
bcs->proto2 = L2_HDLC;
dev_warn(cs->dev,
- "B2 Protocol X.75 SLP unsupported, using Transparent\n");
+ "B2 Protocol X.75 SLP unsupported, using Transparent\n");
} else {
switch (cmsg->B1protocol) {
case 0:
@@ -1594,46 +1625,46 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
break;
default:
dev_warn(cs->dev,
- "B1 Protocol %u unsupported, using Transparent\n",
+ "B1 Protocol %u unsupported, using Transparent\n",
cmsg->B1protocol);
bcs->proto2 = L2_VOICE;
}
if (cmsg->B2protocol != 1)
dev_warn(cs->dev,
- "B2 Protocol %u unsupported, using Transparent\n",
+ "B2 Protocol %u unsupported, using Transparent\n",
cmsg->B2protocol);
if (cmsg->B3protocol != 0)
dev_warn(cs->dev,
- "B3 Protocol %u unsupported, using Transparent\n",
+ "B3 Protocol %u unsupported, using Transparent\n",
cmsg->B3protocol);
ignore_cstruct_param(cs, cmsg->B1configuration,
- "CONNECT_RESP", "B1 Configuration");
+ "CONNECT_RESP", "B1 Configuration");
ignore_cstruct_param(cs, cmsg->B2configuration,
- "CONNECT_RESP", "B2 Configuration");
+ "CONNECT_RESP", "B2 Configuration");
ignore_cstruct_param(cs, cmsg->B3configuration,
- "CONNECT_RESP", "B3 Configuration");
+ "CONNECT_RESP", "B3 Configuration");
}
/* ToDo: check/encode remaining parameters */
ignore_cstruct_param(cs, cmsg->ConnectedNumber,
- "CONNECT_RESP", "Connected Number");
+ "CONNECT_RESP", "Connected Number");
ignore_cstruct_param(cs, cmsg->ConnectedSubaddress,
- "CONNECT_RESP", "Connected Subaddress");
+ "CONNECT_RESP", "Connected Subaddress");
ignore_cstruct_param(cs, cmsg->LLC,
- "CONNECT_RESP", "LLC");
+ "CONNECT_RESP", "LLC");
if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
ignore_cstruct_param(cs, cmsg->BChannelinformation,
- "CONNECT_RESP", "BChannel Information");
+ "CONNECT_RESP", "BChannel Information");
ignore_cstruct_param(cs, cmsg->Keypadfacility,
- "CONNECT_RESP", "Keypad Facility");
+ "CONNECT_RESP", "Keypad Facility");
ignore_cstruct_param(cs, cmsg->Useruserdata,
- "CONNECT_RESP", "User-User Data");
+ "CONNECT_RESP", "User-User Data");
ignore_cstruct_param(cs, cmsg->Facilitydataarray,
- "CONNECT_RESP", "Facility Data Array");
+ "CONNECT_RESP", "Facility Data Array");
}
/* Accept call */
- if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
+ if (!gigaset_add_event(cs, &cs->bcs[channel - 1].at_state,
EV_ACCEPT, NULL, 0, NULL))
return;
gigaset_schedule_event(cs);
@@ -1676,7 +1707,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
if (oap != ap) {
spin_unlock_irqrestore(&bcs->aplock, flags);
send_disconnect_ind(bcs, oap,
- CapiCallGivenToOtherApplication);
+ CapiCallGivenToOtherApplication);
spin_lock_irqsave(&bcs->aplock, flags);
}
}
@@ -1687,7 +1718,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
/* reject call - will trigger DISCONNECT_IND for this app */
dev_info(cs->dev, "%s: Reject=%x\n",
"CONNECT_RESP", cmsg->Reject);
- if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
+ if (!gigaset_add_event(cs, &cs->bcs[channel - 1].at_state,
EV_HUP, NULL, 0, NULL))
return;
gigaset_schedule_event(cs);
@@ -1720,7 +1751,7 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
send_conf(iif, ap, skb, CapiIllContrPlciNcci);
return;
}
- bcs = &cs->bcs[channel-1];
+ bcs = &cs->bcs[channel - 1];
/* mark logical connection active */
bcs->apconnstate = APCONN_ACTIVE;
@@ -1730,8 +1761,9 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
/* NCPI parameter: not applicable for B3 Transparent */
ignore_cstruct_param(cs, cmsg->NCPI, "CONNECT_B3_REQ", "NCPI");
- send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
- CapiNcpiNotSupportedByProtocol : CapiSuccess);
+ send_conf(iif, ap, skb,
+ (cmsg->NCPI && cmsg->NCPI[0]) ?
+ CapiNcpiNotSupportedByProtocol : CapiSuccess);
}
/*
@@ -1765,7 +1797,7 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
dev_kfree_skb_any(skb);
return;
}
- bcs = &cs->bcs[channel-1];
+ bcs = &cs->bcs[channel - 1];
if (cmsg->Reject) {
/* Reject: clear B3 connect received flag */
@@ -1846,6 +1878,9 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
/* check for active logical connection */
if (bcs->apconnstate >= APCONN_ACTIVE) {
+ /* clear it */
+ bcs->apconnstate = APCONN_SETUP;
+
/*
* emit DISCONNECT_B3_IND with cause 0x3301
* use separate cmsg structure, as the content of iif->acmsg
@@ -1865,10 +1900,12 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
if (b3skb == NULL) {
dev_err(cs->dev, "%s: out of memory\n", __func__);
send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+ kfree(b3cmsg);
return;
}
capi_cmsg2message(b3cmsg,
- __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
+ __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
+ dump_cmsg(DEBUG_CMD, __func__, b3cmsg);
kfree(b3cmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
}
@@ -1910,7 +1947,7 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
send_conf(iif, ap, skb, CapiIllContrPlciNcci);
return;
}
- bcs = &cs->bcs[channel-1];
+ bcs = &cs->bcs[channel - 1];
/* reject if logical connection not active */
if (bcs->apconnstate < APCONN_ACTIVE) {
@@ -1928,9 +1965,10 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
/* NCPI parameter: not applicable for B3 Transparent */
ignore_cstruct_param(cs, cmsg->NCPI,
- "DISCONNECT_B3_REQ", "NCPI");
- send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
- CapiNcpiNotSupportedByProtocol : CapiSuccess);
+ "DISCONNECT_B3_REQ", "NCPI");
+ send_conf(iif, ap, skb,
+ (cmsg->NCPI && cmsg->NCPI[0]) ?
+ CapiNcpiNotSupportedByProtocol : CapiSuccess);
}
/*
@@ -1951,11 +1989,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
u16 handle = CAPIMSG_HANDLE_REQ(skb->data);
/* frequent message, avoid _cmsg overhead */
- dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);
-
- gig_dbg(DEBUG_LLDATA,
- "Receiving data from LL (ch: %d, flg: %x, sz: %d|%d)",
- channel, flags, msglen, datalen);
+ dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
/* check parameters */
if (channel == 0 || channel > cs->channels || ncci != 1) {
@@ -1964,7 +1998,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
send_conf(iif, ap, skb, CapiIllContrPlciNcci);
return;
}
- bcs = &cs->bcs[channel-1];
+ bcs = &cs->bcs[channel - 1];
if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
dev_notice(cs->dev, "%s: unexpected length %d\n",
"DATA_B3_REQ", msglen);
@@ -2007,7 +2041,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION))
send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle,
flags ? CapiFlagsNotSupportedByProtocol
- : CAPI_NOERROR);
+ : CAPI_NOERROR);
}
/*
@@ -2026,12 +2060,6 @@ static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
}
/*
- * dump unsupported/ignored messages at most twice per minute,
- * some apps send those very frequently
- */
-static unsigned long ignored_msg_dump_time;
-
-/*
* unsupported CAPI message handler
*/
static void do_unsupported(struct gigaset_capi_ctr *iif,
@@ -2040,8 +2068,7 @@ static void do_unsupported(struct gigaset_capi_ctr *iif,
{
/* decode message */
capi_message2cmsg(&iif->acmsg, skb->data);
- if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000))
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+ dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
}
@@ -2052,11 +2079,9 @@ static void do_nothing(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
- if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) {
- /* decode message */
- capi_message2cmsg(&iif->acmsg, skb->data);
- dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
- }
+ /* decode message */
+ capi_message2cmsg(&iif->acmsg, skb->data);
+ dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
dev_kfree_skb_any(skb);
}
@@ -2064,7 +2089,7 @@ static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
- dump_rawmsg(DEBUG_LLDATA, __func__, skb->data);
+ dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
dev_kfree_skb_any(skb);
}
@@ -2225,11 +2250,11 @@ static int gigaset_proc_show(struct seq_file *m, void *v)
seq_printf(m, "%-16s %s\n", "name", ctr->name);
seq_printf(m, "%-16s %s %s\n", "dev",
- dev_driver_string(cs->dev), dev_name(cs->dev));
+ dev_driver_string(cs->dev), dev_name(cs->dev));
seq_printf(m, "%-16s %d\n", "id", cs->myid);
if (cs->gotfwver)
seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
- cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
+ cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
seq_printf(m, "%-16s %d\n", "channels", cs->channels);
seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");
@@ -2282,13 +2307,13 @@ static int gigaset_proc_show(struct seq_file *m, void *v)
for (i = 0; i < cs->channels; i++) {
seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
- cs->bcs[i].corrupted);
+ cs->bcs[i].corrupted);
seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
- cs->bcs[i].trans_down);
+ cs->bcs[i].trans_down);
seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
- cs->bcs[i].trans_up);
+ cs->bcs[i].trans_up);
seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
- cs->bcs[i].chstate);
+ cs->bcs[i].chstate);
switch (cs->bcs[i].proto2) {
case L2_BITSYNC:
s = "bitsync";
@@ -2309,7 +2334,7 @@ static int gigaset_proc_show(struct seq_file *m, void *v)
static int gigaset_proc_open(struct inode *inode, struct file *file)
{
- return single_open(file, gigaset_proc_show, PDE(inode)->data);
+ return single_open(file, gigaset_proc_show, PDE_DATA(inode));
}
static const struct file_operations gigaset_proc_fops = {
@@ -2325,7 +2350,7 @@ static const struct file_operations gigaset_proc_fops = {
* @cs: device descriptor structure.
* @isdnid: device name.
*
- * Return value: 1 for success, 0 for failure
+ * Return value: 0 on success, error code < 0 on failure
*/
int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
{
@@ -2335,7 +2360,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
iif = kmalloc(sizeof(*iif), GFP_KERNEL);
if (!iif) {
pr_err("%s: out of memory\n", __func__);
- return 0;
+ return -ENOMEM;
}
/* prepare controller structure */
@@ -2359,12 +2384,12 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
if (rc) {
pr_err("attach_capi_ctr failed (%d)\n", rc);
kfree(iif);
- return 0;
+ return rc;
}
cs->iif = iif;
cs->hw_hdr_len = CAPI_DATA_B3_REQ_LEN;
- return 1;
+ return 0;
}
/**