aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/isdn/gigaset/capi.c83
1 files changed, 51 insertions, 32 deletions
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index cb55ead557cc..e685123fef48 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -320,6 +320,39 @@ static const char *format_ie(const char *ie)
320 return result; 320 return result;
321} 321}
322 322
323/*
324 * emit DATA_B3_CONF message
325 */
326static void send_data_b3_conf(struct cardstate *cs, struct capi_ctr *ctr,
327 u16 appl, u16 msgid, int channel,
328 u16 handle, u16 info)
329{
330 struct sk_buff *cskb;
331 u8 *msg;
332
333 cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
334 if (!cskb) {
335 dev_err(cs->dev, "%s: out of memory\n", __func__);
336 return;
337 }
338 /* frequent message, avoid _cmsg overhead */
339 msg = __skb_put(cskb, CAPI_DATA_B3_CONF_LEN);
340 CAPIMSG_SETLEN(msg, CAPI_DATA_B3_CONF_LEN);
341 CAPIMSG_SETAPPID(msg, appl);
342 CAPIMSG_SETCOMMAND(msg, CAPI_DATA_B3);
343 CAPIMSG_SETSUBCOMMAND(msg, CAPI_CONF);
344 CAPIMSG_SETMSGID(msg, msgid);
345 CAPIMSG_SETCONTROLLER(msg, ctr->cnr);
346 CAPIMSG_SETPLCI_PART(msg, channel);
347 CAPIMSG_SETNCCI_PART(msg, 1);
348 CAPIMSG_SETHANDLE_CONF(msg, handle);
349 CAPIMSG_SETINFO_CONF(msg, info);
350
351 /* emit message */
352 dump_rawmsg(DEBUG_MCMD, __func__, msg);
353 capi_ctr_handle_message(ctr, appl, cskb);
354}
355
323 356
324/* 357/*
325 * driver interface functions 358 * driver interface functions
@@ -340,7 +373,6 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
340 struct gigaset_capi_ctr *iif = cs->iif; 373 struct gigaset_capi_ctr *iif = cs->iif;
341 struct gigaset_capi_appl *ap = bcs->ap; 374 struct gigaset_capi_appl *ap = bcs->ap;
342 unsigned char *req = skb_mac_header(dskb); 375 unsigned char *req = skb_mac_header(dskb);
343 struct sk_buff *cskb;
344 u16 flags; 376 u16 flags;
345 377
346 /* update statistics */ 378 /* update statistics */
@@ -357,34 +389,17 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
357 return; 389 return;
358 } 390 }
359 391
360 /* ToDo: honor unset "delivery confirmation" bit */ 392 /*
393 * send DATA_B3_CONF if "delivery confirmation" bit was set in request;
394 * otherwise it has already been sent by do_data_b3_req()
395 */
361 flags = CAPIMSG_FLAGS(req); 396 flags = CAPIMSG_FLAGS(req);
362 397 if (flags & CAPI_FLAGS_DELIVERY_CONFIRMATION)
363 /* build DATA_B3_CONF message */ 398 send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req),
364 cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC); 399 bcs->channel + 1, CAPIMSG_HANDLE_REQ(req),
365 if (!cskb) { 400 (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ?
366 dev_err(cs->dev, "%s: out of memory\n", __func__); 401 CapiFlagsNotSupportedByProtocol :
367 return; 402 CAPI_NOERROR);
368 }
369 /* frequent message, avoid _cmsg overhead */
370 CAPIMSG_SETLEN(cskb->data, CAPI_DATA_B3_CONF_LEN);
371 CAPIMSG_SETAPPID(cskb->data, ap->id);
372 CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3);
373 CAPIMSG_SETSUBCOMMAND(cskb->data, CAPI_CONF);
374 CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(req));
375 CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr);
376 CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1);
377 CAPIMSG_SETNCCI_PART(cskb->data, 1);
378 CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(req));
379 if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION)
380 CAPIMSG_SETINFO_CONF(cskb->data,
381 CapiFlagsNotSupportedByProtocol);
382 else
383 CAPIMSG_SETINFO_CONF(cskb->data, CAPI_NOERROR);
384
385 /* emit message */
386 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_CONF", cskb->data);
387 capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
388} 403}
389EXPORT_SYMBOL_GPL(gigaset_skb_sent); 404EXPORT_SYMBOL_GPL(gigaset_skb_sent);
390 405
@@ -1795,6 +1810,8 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
1795 u16 msglen = CAPIMSG_LEN(skb->data); 1810 u16 msglen = CAPIMSG_LEN(skb->data);
1796 u16 datalen = CAPIMSG_DATALEN(skb->data); 1811 u16 datalen = CAPIMSG_DATALEN(skb->data);
1797 u16 flags = CAPIMSG_FLAGS(skb->data); 1812 u16 flags = CAPIMSG_FLAGS(skb->data);
1813 u16 msgid = CAPIMSG_MSGID(skb->data);
1814 u16 handle = CAPIMSG_HANDLE_REQ(skb->data);
1798 1815
1799 /* frequent message, avoid _cmsg overhead */ 1816 /* frequent message, avoid _cmsg overhead */
1800 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data); 1817 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);
@@ -1845,12 +1862,14 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
1845 return; 1862 return;
1846 } 1863 }
1847 1864
1848 /* DATA_B3_CONF reply will be sent by gigaset_skb_sent() */
1849
1850 /* 1865 /*
1851 * ToDo: honor unset "delivery confirmation" bit 1866 * DATA_B3_CONF will be sent by gigaset_skb_sent() only if "delivery
1852 * (send DATA_B3_CONF immediately?) 1867 * confirmation" bit is set; otherwise we have to send it now
1853 */ 1868 */
1869 if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION))
1870 send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle,
1871 flags ? CapiFlagsNotSupportedByProtocol
1872 : CAPI_NOERROR);
1854} 1873}
1855 1874
1856/* 1875/*