summaryrefslogtreecommitdiffstats
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.c118
1 files changed, 53 insertions, 65 deletions
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 343b5c80cb7b..27e4a3e21d64 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -14,6 +14,7 @@
#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>
@@ -108,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 */
};
/*
@@ -223,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) {
@@ -1192,7 +1181,9 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
confparam[3] = 2; /* length */
capimsg_setu16(confparam, 4, CapiSuccess);
break;
- /* ToDo: add supported services */
+
+ /* ToDo: add supported services */
+
default:
dev_notice(cs->dev,
"%s: unsupported supplementary service function 0x%04x\n",
@@ -1766,7 +1757,8 @@ 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]) ?
+ send_conf(iif, ap, skb,
+ (cmsg->NCPI && cmsg->NCPI[0]) ?
CapiNcpiNotSupportedByProtocol : CapiSuccess);
}
@@ -1882,6 +1874,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
@@ -1906,6 +1901,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
}
capi_cmsg2message(b3cmsg,
__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);
}
@@ -1966,7 +1962,8 @@ 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]) ?
+ send_conf(iif, ap, skb,
+ (cmsg->NCPI && cmsg->NCPI[0]) ?
CapiNcpiNotSupportedByProtocol : CapiSuccess);
}
@@ -2059,12 +2056,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,
@@ -2073,8 +2064,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);
}
@@ -2085,11 +2075,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);
}
@@ -2358,7 +2346,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)
{
@@ -2368,7 +2356,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 */
@@ -2392,12 +2380,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;
}
/**