diff options
Diffstat (limited to 'drivers/isdn/gigaset/capi.c')
-rw-r--r-- | drivers/isdn/gigaset/capi.c | 118 |
1 files changed, 53 insertions, 65 deletions
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 343b5c80cb7..27e4a3e21d6 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; } /** |