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.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 6fbe8999c41..bcc174e4f3b 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -45,6 +45,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)
@@ -270,9 +271,13 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
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);
+ 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;
@@ -378,13 +383,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;
}
@@ -422,13 +427,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 +460,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);
@@ -747,7 +753,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 +849,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 +907,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;
}
@@ -978,6 +983,9 @@ static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
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 +1052,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 +1071,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 +1153,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 +1170,32 @@ 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 */
@@ -1951,11 +1986,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) {
@@ -2064,7 +2095,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);
}